Working with Dates and Time


Beside the traditional date formats (YMD, YMDHMS, in strings or numerical representation), nnCron also uses two other methods of date representation: DATE FILETIME.

DATE is number which in binary representation looks like this: yyyyyyyyyyymmmmddddd, i. e. five last bits represent a day of the month, four preceding bits represent a month, and all the remaining bits are used to record a year. Therefore, DATE only contains information about a year, month and day, but not about hours, minutes or seconds. DATE format is used, for example, by such words as FILE-CREATION-DATE:, FILE-ACCESS-DATE:, FILE-WRITE-DATE:, as well as words used inside of FOR-FILES: loop (CREATION-DATE, ACCESS-DATE, WRITE-DATE).

FILETIME permits to access not just values of year, month and day of the month, but also hours, minutes, seconds and milliseconds. FILETIME is a double number which contains the number of 100-nanosecond intervals from January 1st 1601 to the specified moment. FILETIME format is used, for example, by words from plugin time.spf (FILE-TIME:, FILE-ATIME:, FILE-WTIME:). We are strongly recommending using FILETIME format when working with dates and time.

If necessary, you can convert dates between formats YMD, DATE and FILETIME.



ASSUMED-NEXT-TIME ( -- d t= | -- f= )
ASSUMED-PREV-TIME ( -- d t= | -- f= )

When used inside the task these words give you an access to the information about the dates, when this task was scheduled to run for the next and the last time.

The word ASSUMED-NEXT-TIME returns TRUE flag and assumed date when the task is scheduled to run for the next time or single FALSE flag if nnCron can't determine the date. The word ASSUMED-PREV-TIME returns TRUE flag and assumed date when the task was scheduled to run for the last time (even when this time was missed) or single FALSE flag if nnCron can't determine the date.

Both words are returning time in FILETIME format.

Examples:

#( test_assumed_time 
\ printing assumed time of the next scheduled
\ task run to console every 2 minutes 
Time: */2
Action:
    ASSUMED-NEXT-TIME 
    IF
        FT>DD.MM.YYYY/hh:mm:ss TYPE CR 
    THEN
)#

#( test_assumed_time1
\ creating special words and printing assumed times
\ of the last and the next scheduled task run to
\ console every 3 minutes
: FT. FT>DD.MM.YYYY/hh:mm:ss TYPE ;
: ?FT. IF FT. ELSE ." none" THEN ;
Time: */3
Action:
   ASSUMED-NEXT-TIME ?FT. CR
   ASSUMED-PREV-TIME ?FT. CR
)#

CUR-DATE ( -- u )

Puts on stack the value of current date (in DATE format). This word is used to compare various dates, e.g. date of creation of (last access to, last modification of) a file with the current date (details).


DATE>S ( u -- a u )

Converts a date from DATE format to a string "DD-MM-YYYY".

Examples:

\ printing the current date to console
CUR-DATE DATE>S TYPE

#( test_message
NoActive Action: \ displaying a current date in a message box MSG: "Current date: %CUR-DATE DATE>S%" )#

DATE- ( u1 u2 -- u )

Returns a difference (in days) between two dates in DATE format.

Examples:

\ placing the current date on stack
CUR-DATE
\ converting "December 31 2002" to  DATE format
2002 12 31 YMD>DATE
\ calculating the difference between these two dates (in days)
DATE- . CR

DATE-INTERVAL: dd1.mm1.yyyy1-dd2.mm2.yyyy2[/days]

Returns TRUE (-1) if the current date belongs to a specified interval.
The third parameter is optional, and it is only used if you want to check for this condition periodically. It sets the interval between consecutive checks (in days).

See also: INTERVAL: hh1:mm1-hh2:mm2[/hh3:mm3]


DAY+ ( y m d days -- y1 m1 d1 )

This word "adds" or "subtracts" any desired number of days to/from a date in YMD format (taking in account the number of days in each month of a year and number of months in a year) and returns the resulting date in the same format.

Example:

\ adding one day to "December 31 2002",
\ printing to console the result: 1 1 2003 ("January 1st 2003").
2002 12 31 1 DAY+ . . . CR

To "subtract" any desired number of days from a date in YMD format, just use a negative value when specifying number of a days to subtract.

Example:

\ subtracting one day from "December 31 2002",
\ printing to console the result: 30 12 2002 ("December 30th 2002").
2002 12 31 -1 DAY+ . . . CR


DAYS ( y m d -- days )

Puts on stack the number of days from the starting point of Gregorian calendar to the specified date. Accepts a date in YMD format as its argument.

Example:

\ printing to console the total number 
\ of days before January 1st, 2003
2003 1 1 DAYS . CR

Days@

Puts on stack the number of days from the starting point of Gregorian calendar to the current date.


FT-

Returns a difference between two dates in FILETIME format. To convert the result (for example) to seconds, use word FT>SEC.

Example:

\ noting the current time twice and placing on stack
\ the difference in seconds
FT-CUR
10000 PAUSE
FT-CUR FT- FT>SEC D>S . CR


FT-CUR

Converts the current date and time to FILETIME format.

Example:

#( test_file_time
\ if file '1.sem' was created more then 2 minutes ago,,
\ we'll do something useful
Action:
FT-CUR FILE-TIME: "C:\1.sem" FTIME- 120 >
IF
    \ ... doing the required job
THEN
)#


FT>DAY
FT>HOUR
FT>MIN

These words convert the specified date and time in FILETIME format to number of days, hours or minutes respectively.


FT>DD.MM.YYYY/hh:mm:ss ( d - a u)

This word converts the specified date and time in FILETIME format to a string "DD.MM.YYYY/hh:mm:ss".

:

\ printing to console current date and time (31.03.3003/14:40:47)
FT-CUR FT>DD.MM.YYYY/hh:mm:ss TYPE CR

FT>MS
FT>SEC

These words convert the specified date and time in FILETIME format to number of milliseconds or seconds respectively. They return a double number .


GET-CUR-TIME

"Renews" the current time value. nnCron does this automatically once a minute, so that the number seconds remains the same during the entire minute. Use GET-CUR-TIME to forcibly renew the number of seconds.

Examples:

\ each second during a minute 
\ writing the precise current time to a log file:
#( test_cur_time
NoActive
Action:
    60 0 DO
    GET-CUR-TIME
    LOG: "log\idle.log" "%hh%:%mm%:%ss% - current time"
    PAUSE: 1000
    LOOP
)#
   
\ printing to console the exact value of the current second
GET-CUR-TIME Sec@

GetTickCount

Puts on stack the number of milliseconds elapsed since startup of operating system. The elapsed time is returned as a DWORD value. Therefore, the time will wrap around to zero if the system is run continuously for 49.7 days.

Example:

\ the task will be started 
\ if the OS was started less then 90 seconds ago 
Rule: GetTickCount 90000 <

See also: UPTIME


INTERVAL: hh1:mm1-hh2:mm2[/hh3:mm3]

Returns TRUE (-1) if the current time belongs to a specified interval.
The third parameter is optional, and it is only used if you want to check for this condition periodically. It sets the interval between consecutive checks (in hours and minutes).

\ this rule will return  'TRUE' at 10:00, 10:45 and 11:30 
\ (i.e. with  intervals of 45 minutes)
Rule: INTERVAL: 10:00-12:00/00:45
\ this rule will return 'TRUE' at  10:00, 11:01, 12:02 and 13:03 
\ (.e. with  intervals of 61 minute)
Rule: INTERVAL: 10:00-14:00/01:01

Examples:

#( test_interval
WatchConnect
Rule: INTERVAL: 10:00-18:00
Action:
    \ ... performing some useful actions
)#
#( test_interval1 \ performing the action each 30 minutes, from 10:00 to 18:00 inclusive Rule: INTERVAL: 10:00-18:00/00:30 Action: MSG: "Half an hour has passed!" )#

See also: DATE-INTERVAL: dd1.mm1.yyyy1-dd2.mm2.yyyy2[/days]


FT>DATE
FT>YMDHMS
DATE>YMD
YMD>DATE
YMDHMS>FT

These words convert dates between formatsYMD (YMDHMS), DATE and FILETIME.

Examples:

\ FILETIME  DATE
FT-CUR FT>DATE
\ FILETIME  YMDHMS
FT-CUR FT>YMDHMS
\ DATE  YMD
CUR-DATE DATE>YMD
\ YMD  DATE
2002 12 31 YMD>DATE
\ YMDHMS  FILETIME
2002 12 31 0 0 0 YMDHMS>FT

Sec@
Min@
Hour@
Day@
Mon@
WDay@
Year@

This words put on stack the value of the current second, minute, hour, day, month, day of the week, and year respectively. Please note that to receive a correct value for seconds you will have to use word GET-CUR-TIME.

Example:

\ placing on stack the current date in YMD format
Year@ Mon@ Day@
\ placing on stack the current date in YMDHMS format
Year@ Mon@ Day@ Hour@ Min@ GET-CUR-TIME Sec@

MonLength ( year month -- days-of-month )

Returns the number of days in a specified month. This word uses the year and the number of desired month as its arguments.

Example:

\ printing to console the number of days in February 2003
2003 2 MonLength . CR

WDAYS
MONNAMES

These predefined arrays contain shortened names of days of week and of months. WDAYS contains characters "MonTueWedThuFriSatSun", and MONNAMES contains characters "JanFebMarAprMayJunJulAugSepOctNovDec". You can use these arrays to access a name of a day of week (or of a month) by their number. Please not that numbering of days of a week starts with Monday (in other words, Monday is considered to be the first day of a week, and Sunday the seventh).

Examples:

\ printing to console the name of the 1st month
1 1- 3 * MONNAMES COUNT DROP + 3 TYPE CR
\ printing to console the name of the 12th month
12 1- 3 * MONNAMES COUNT DROP + 3 TYPE CR
\ printing to console the name of the third day of week
3 1- 3 * WDAYS COUNT DROP + 3 TYPE CR
\ printing to console the name of the fifth day of week
5 1- 3 * WDAYS COUNT DROP + 3 TYPE CR 

SD.M.Y>Day ( addr u -- days )

This word receives a string describing a date in DD.MM.YYYY format and returns (puts on stack) the number of days from the starting point of Gregorian calendar to the specified date.

Example:

\ printing to console the total number
\ that has passed before  31.12.2002
S" 31.12.2002" SD.M.Y>Day . CR

SDD.MM.YYYY ( addr u -- y m d )

Converts a string (in DD.MM.YYYY format) into a date in YMD format.

Example:

\ converting string "31.12.2002" to 3 numbers (YMD)
\ and printing them to console
S" 31.12.2002" SDD.MM.YYYY . . . CR

SH:M>Min

This word takes as its argument a string describing time in HH:MM format and converts it to a number equal to the number of minutes.

Examples:

\ converting strings "1:20" and "01:20" 
\ into number of minutes (80)
S" 1:20" SH:M>Min . CR
S" 01:20" SH:M>Min . CR

START-TIME?

Checks if the current time is the top of the first minute after nnCron startup. Returns TRUE (-1) if current time is the top of the first minute after nnCron startup and FALSE (0) otherwise. This word should be used for example to avoid task start on nnCron startup.

Example:

#( test_nostartup
\ this task will be started every
\ minute but not on nnCron startup
Rule: START-TIME? 0=
Action:
    \ ...
)#

TASK-CREATION-TIME ( -- d t= | -- f=)
TASK-EXECUTION-TIME ( -- d t= | -- f=)

When used inside the task these words give you an access to the information about the date, when this task was created (to be more specific, this is the date of the last modification of the Time: field) and the date when this task was executed for the last time.

The word TASK-CREATION-TIME returns TRUE flag and the date when the task was created or single FALSE flag if nnCron can't determine the date. The word TASK-EXECUTION-TIME returns TRUE flag and the date when the task was executed for the last time or single FALSE flag if nnCron can't determine the date.

Both words are returning time in FILETIME format.

Examples:

#( test_task_time 
\ printing the time when the task was
\ created to console every 2 minutes 
Time: */2
Action:
    TASK-CREATION-TIME 
    IF
        FT>DD.MM.YYYY/hh:mm:ss TYPE CR 
    THEN
)#

#( test_task_time1
\ creating special words and printing the times
\ when the task was created and executed for the
\ last time to console every 3 minutes
: FT. FT>DD.MM.YYYY/hh:mm:ss TYPE ;
: ?FT. IF FT. ELSE ." none" THEN ;
Time: */3
Action:
   TASK-CREATION-TIME ?FT. CR
   TASK-EXECUTION-TIME ?FT. CR
)#

TimeMin@ ( -- CurrentTime_in_minutes )
TimeSec@ ( -- CurrentTime_in_seconds )

This words put on stack the current time in minutes or seconds respectively (the number of minutes/seconds since the last midnight).

Examples:

\ printing to console the current time in minutes/seconds
TimeMin@ . CR
TimeSec@ . CR

WEEKDAY ( y m d -- wd[1-7] )

This word takes a date in YMD format and returns (puts on stack) the corresponding number of day of a week (1 ... 7, 1 being Monday).

Example:

\ printing to console the number of day of a week
\ which was December 31, 2002
2002 12 31 WEEKDAY . CR

See also: