Date! values represent calendar dates, relying on the Gregorian calendar. A date value can also contain optional time and timezone information. Time in dates is expressed in 24-hour format (including optional time zone information). Red’s dates also have an extensive support for ISO 8601 input formats.
|
Note
|
|
Date! values can be created using literal syntax, or at runtime using a make constructor or a to conversion.
Many different literal formats are supported, including all Rebol date formats and most of the ISO date standard.
<date>/<time>
<date>/<time><zone>
<date>T<time>
<date>T<time>Z
<date>T<time><zone>
<date> formats:
<yyyy><sep><mmm><sep><dd>
<dd><sep><mmm><sep><yyyy>
<dd><sep><mmm><sep><yy>
Additional <date> formats when followed by T:
<yyyy><mm><dd>
<yyyy>-W<ww>
<yyyy>-W<ww>-<d>
<yyyy>-<ddd>
<mmm> formats (month):
<m>
<mon>
<month>
<time> formats:
<hour>:<min>:<sec>
<hour>:<min>:<sec><zone>
<hhmmss>
<hhmmss><zone>
<hhmmss>.<dec>
<hhmmss>.<dec><zone>
<hhmm>
<hhmm><zone>
<zone> formats (timezone):
<sign><hour>
<sign><hour>:<min15>
<sign><hhmm>
<sec> formats (seconds):
<ss>
<ss>.<dec>
<sep> : `-` or `/`
<yyyy> : 3 or 4 digits representing the year (4 digits for ISO dates)
<yy> : 2 digits representing the year relative to 2000
<m> : 1 or 2 digits representing the month
<mm> : 2 digits representing the month
<mon> : 3 letters representing the beginning of the month
<month> : full name of the month
<d> : a digit representing the day of the week (1 to 7)
<dd> : 1 or 2 digits representing the day of the month
<ddd> : 3 digits representing the day of the year
<ww> : 2 digits representing the week of the year
<time> : time! value
<hour> : 1 or 2 digits representing the hours
<min> : 1 or 2 digits representing the minutes
<ss> : 1 or 2 digits representing the seconds
<dec> : decimals for seconds
<sign> : `+` or `-` character (cannot be omitted)
<min15> : same as <min> but rounded to a multiple of 15.
<hhmm> : 4 digits for hours and minutes (no separator)
<hhmmss> : 6 digits for hours, minutes and seconds (no separator)
Many different input formats for literal dates are accepted. Out of range values (exceeding the specified digit numbers or beyond a field’s norm) will result in a syntax error. When serialized again (e.g. for displaying), only the following canonical formats are used:
<dd>-<mon>-<yyyy> <dd>-<mon>-<yyyy>/<hour>:<min>:<sec> <dd>-<mon>-<yyyy>/<hour>:<min>:<sec><sign><hour>:<min15>
When the time and/or zone fields are unset, they are omitted. For negative dates, the / separator is used instead of - for better readability.
|
Note
|
|
Examples of valid input dates:
1999-10-5 1999/10/5 5-10-1999 5/10/1999 5-October-1999 1999-9-11 11-9-1999 5/sep/2012 5-SEPTEMBER-2012 02/03/04 02/03/71 5/9/2012/6:0 5/9/2012/6:00 5/9/2012/6:00+8 5/9/2012/6:0+0430 4/Apr/2000/6:00+8:00 1999-10-2/2:00-4:30 1/1/1990/12:20:25-6 2017-07-07T08:22:23+00:00 2017-07-07T08:22:23Z 20170707T082223Z 20170707T0822Z 20170707T082223+0530 2017-W01 2017-W23-5 2017-W23-5T10:50Z 2017-001 2017-153T10:50:00-4:00
make date! [<day> <month> <year>] make date! [<year> <month> <day>] make date! [<day> <month> <year> <time>] make date! [<day> <month> <year> <time> <zone>] make date! [<day> <month> <year> <time> <zone-h>] make date! [<day> <month> <year> <time> <zone-h> <zone-m>] make date! [<day> <month> <year> <hour>] make date! [<day> <month> <year> <hour> <minute>] make date! [<day> <month> <year> <hour> <minute> <second>] make date! [<day> <month> <year> <hour> <minute> <second> <zone>] make date! [<day> <month> <year> <hour> <minute> <second> <zone-h>] make date! [<day> <month> <year> <hour> <minute> <second> <zone-h> <zone-m>] <year> : integer! value <month> : integer! value <day> : integer! value <time> : time! value <zone> : integer!, time! or pair! value <hour> : integer! value <minute> : integer! value <second> : integer! value
|
Note
|
|
Examples
make date! [1978 2 3] == 3-Feb-1978 make date! [1978 2 3 5:0:0 8] == 3-Feb-1978/5:00:00+08:00 make date! [1978 2 3 5:0:0] == 3-Feb-1978/5:00:00 make date! [1978 2 3 5 20 30] == 3-Feb-1978/5:20:30 make date! [1978 2 3 5 20 30 -4] == 3-Feb-1978/5:20:30-4:00 make date! [100 12 31] == 31-Dec-0100 ; 32 isn't a valid day make date! [100 12 32] *** Script Error: cannot MAKE/TO date! from: [100 12 32] *** Where: make ; First field is < 100, so not considered as a year make date! [99 12 31] *** Script Error: cannot MAKE/TO date! from: [99 12 31] *** Where: make
-
Using a
toconversion (see 4.1 [_epoch_time]).
to-integer <date> to-date <epoch> <date> : a date! value <epoch> : an integer value representing an epoch time
Path accessors provide a convenient way for getting and setting all date! value fields.
Syntax
<date>/date <date>/date: <date2> <date> : a word or path expression referring to a date! value <date2> : a date! value
Description
Gets or sets the date field of a date (excluding time and zone). Dates are returned as date! values.
Examples
d: now == 10-Jul-2017/22:46:22-06:00 d/date == 10-Jul-2017 d/date: 15/09/2017 == 15-Sep-2017/22:46:22-06:00
Syntax
<date>/year <date>/year: <year> <date> : a word or path expression referring to a date! value <year> : an integer! value
Description
Gets or sets the year field of a date. Years are returned as integers. Out of range argument values will result in a normalized date.
Examples
d: now == 10-Jul-2017/22:46:22-06:00 d/year: 16383 == 16383 d == 10-Jul-16383/22:46:22-06:00 d/year: 16384 == 16384 d == 10/Jul/-16384/22:46:22-06:00 ; note wrap on overflow past year 16384 d/year: 32767 == 32767 d == 10/Jul/-1/22:46:22-06:00 d/year: 32768 == 32768 d == 10-Jul-0000/22:46:22-06:00
Syntax
<date>/month <date>/month: <month> <date> : a word or path expression referring to a date! value <month> : an integer! value
Description
Gets or sets the month field of a date. Months are returned as integers. Out of range argument values will result in a normalized date.
Examples
d: now == 10-Jul-2017/22:48:31-06:00 d/month: 12 == 12 d == 10-Dec-2017/22:48:31-06:00 d/month: 13 == 13 d == 10-Jan-2018/22:48:31-06:00 ; Note wrap to the next year d/month == 1 ; Month is now normalized
Syntax
<date>/day <date>/day: <day> <date> : a word or path expression referring to a date! value <day> : an integer! value
Description
Gets or sets the day field of a date. Days are returned as integers. Out of range argument values will result in a normalized date.
Examples
d: 1-jan-2017 == 1-Jan-2017 d/day: 32 == 32 d == 1-Feb-2017 d/day: 0 ; Note how zero works, for proper date math == 0 d == 31-Jan-2017
Syntax
<date>/time <date>/time: <time> <date> : a word or path expression referring to a date! value <time> : a time! or none! value
Description
Gets or sets the time field of a date. Times are returned as time! values, or none! value if time is not set, or has been reset (see below). Out of range argument values will result in a normalized date.
If the time is set to a none! value, the time and zone fields are set to zero and will not be shown further.
Examples
d: now == 10-Jul-2017/23:18:54-06:00 d/time: 1:2:3 == 1:02:03 d == 10-Jul-2017/1:02:03-06:00 d/time: none == 10-Jul-2017
Syntax
<date>/hour <date>/hour: <hour> <date> : a word or path expression referring to a date! value <hour> : an integer! value
Description
Gets or sets the hour field of a date. Hours are returned as integer values between 0 and 23. Out of range argument values will result in a normalized date.
Examples
d: now == 10-Jul-2017/23:19:40-06:00 d/hour: 0 == 0 d == 10-Jul-2017/0:19:40-06:00 d/hour: 24 == 24 d == 11-Jul-2017/0:19:40-06:00
Syntax
<date>/minute <date>/minute: <minute> <date> : a word or path expression referring to a date! value <minute> : an integer! value
Description
Gets or sets the minute field of a date. Minutes are returned as integer values between 0 and 59. Out of range argument values will result in a normalized date.
Examples
== 10-Jul-2017/23:20:25-06:00 d/minute: 0 == 0 d == 10-Jul-2017/23:00:25-06:00 d/minute: 60 == 60 d == 11-Jul-2017/0:00:25-06:00
Syntax
<date>/second <date>/second: <second> <date> : a word or path expression referring to a date! value <second> : an integer! or float! value
Description
Gets or sets the second field of a date. Seconds are returned as integer! or float! values between 0 and 59. Out of range argument values will result in a normalized date.
Examples
d: now == 10-Jul-2017/23:21:15-06:00 d/second: 0 == 0 d == 10-Jul-2017/23:21:00-06:00 d/second: -1 == -1 d == 10-Jul-2017/23:20:59-06:00 d/second: 60 == 60 d == 10-Jul-2017/23:21:00-06:00
Syntax
<date>/zone <date>/zone: <zone> <date> : a word or path expression referring to a date! value <zone> : a time! or integer! value
Description
Gets or sets the timezone field of a date. Timezones are returned as time! values between -16:00 and +15:00. Setting the timezone with /zone will only modify that field, time is kept the same. Out of range argument values will result in a normalized date.
When the timezone is set to an integer! argument, the argument represents hours, while minutes are set to 0.
The granularity for timezone’s minutes is 15, non-conforming values will be rounded to closest 15 minutes inferior multiple.
Examples
d: 1/3/2017/5:30:0 d/zone: 8 == 1-Mar-2017/5:30:00+08:00 d/zone: -4:00 == 1-Mar-2017/5:30:00-04:00
|
Note
|
Setting a /zone value to a date that lacks a time value will result in the time value defaulting to 0:0:0.
|
Examples
d: 28-Mar-2019 == 28-Mar-2019 d/zone: 1 d == 28-Mar-2019/0:00:00+01:00
Syntax
<date>/timezone <date>/timezone: <timezone> <date> : a word or path expression referring to a date! value <timezone> : an integer! or time! value
Description
Gets or sets the timezone field of a date. Timezones are returned as time! values between -16:00 and +15:00. Setting the timezone with /timezone will modify both the time and the zone, keeping the new time equivalent to the old one in the new zone. Out of range argument values will result in a normalized date.
When the timezone is set to an integer! argument, the argument represents hours, while minutes are set to 0.
The granularity for timezone’s minutes is 15, non-conforming values will be rounded to closest 15 minutes inferior multiple.
Examples
d: 1/3/2017/5:30:0 d/timezone: 8 == 1-Mar-2017/13:30:00+08:00 d/timezone: -4:00 == 1-Mar-2017/1:30:00-04:00
|
Note
|
|
Syntax
<date>/yearday <date>/yearday: <day> <date> : a word or path expression referring to a date! value <yearday> : an integer! value
Description
Gets the day of the year of a date, starting at 1 for January 1st. Days are returned as integers. When used for setting the day of the year, the date is recalculated to match that day. Out of range argument values will result in a normalized date.
Note:
-
a
/julianalias for/yeardayis also available, for compatibility with Rebol.
Examples
d: 1-jan-2017 == 1-Jan-2017 d/yearday == 1 d: 31-dec-2017 == 31-Dec-2017 d/yearday == 365 d: 31-dec-2020 == 31-Dec-2020 d/yearday == 366 ; Leap year d: 31-dec-2017 == 31-Dec-2017 d/yearday: 366 == 366 d == 1-Jan-2018
Syntax
<date>/weekday <date>/weekday: <day> <date> : a word or path expression referring to a date! value <weekday> : an integer! value
Description
Gets the week day number, ranging from 1 for Monday, to 7 for Sunday (ISO-8601 international format). When used for setting the day of the week, the date is recalculated to match that day in the current week. Out of range argument values will result in a normalized date.
Examples
d: now == 10-Jul-2017/23:25:35-06:00 d/weekday == 1 d/weekday: 2 == 2 d == 11-Jul-2017/23:25:35-06:00 d/weekday: 7 == 7 d == 16-Jul-2017/23:25:35-06:00 d/weekday: 8 == 8 d == 17-Jul-2017/23:25:35-06:00
Syntax
<date>/week <date>/week: <day> <date> : a word or path expression referring to a date! value <week> : an integer! value
Description
Gets the week number using a casual week definition (week starts on Sunday, first week starts on January 1st), ranging from 1 for first week of the year, to 53. When used for setting the week number, the date is recalculated to match the first day of that week (a Sunday). Out of range argument values will result in a normalized date.
|
Note
|
|
Examples
d: now == 10-Jul-2017/23:28:07-06:00 d/week == 28 d/week: 29 == 29 d == 16-Jul-2017/23:28:07-06:00 d/week: 52 == 52 d == 24-Dec-2017/23:28:07-06:00 d/week: 53 == 53 d == 31-Dec-2017/23:28:07-06:00 d/week: 54 == 54 d == 7-Jan-2018/23:28:07-06:00
Syntax
<date>/isoweek <date>/isoweek: <day> <date> : a word or path expression referring to a date! value <isoweek> : an integer! value
Description
Gets the week number using the ISO 8601 week definition, ranging from 1 for first week of the year, to 52 (or 53 for some years). When used for setting the week number, the date is recalculated to match the first day of that week (a Monday). Out of range argument values will result in a normalized date.
Examples
d: now == 10-Jul-2017/23:29:13-06:00 d/isoweek == 28 d/isoweek: 29 == 29 d == 17-Jul-2017/23:29:13-06:00 d/isoweek: 52 == 52 d == 25-Dec-2017/23:29:13-06:00 d/isoweek: 53 == 53 d == 1-Jan-2018/23:29:13-06:00
In addition to using words for accessing the date fields, it is also possible to use an integer index in path expression:
<date>/<index> <date> : a word or path expression referring to a date! value <index> : an integer! value referring to a date field.
Such ordinal accessor can be used both for getting or setting fields. The following table gives the equivalent field names
| Index | Name |
|---|---|
1 |
date |
2 |
year |
3 |
month |
4 |
day |
5 |
zone |
6 |
time |
7 |
hour |
8 |
minute |
9 |
second |
10 |
weekday |
11 |
yearday |
12 |
timezone |
13 |
week |
14 |
isoweek |
It is possible to access date fields without using a path, which can be more convenient in some cases. pick can be used for that on dates.
Syntax
pick <date> <field> <date> : a date! value <field> : an integer! value
An integer argument represents the ordinal accessor for dates. See "Ordinal accessors" table above.
Examples
d: now == 10-Jul-2017/23:35:01-06:00 names: system/catalog/accessors/date! repeat i 14 [print [pad i 4 pad names/:i 10 pick d i]] 1 date 11-Jul-2017 2 year 2017 3 month 7 4 day 11 5 zone 8:00:00 6 time 21:43:52 7 hour 21 8 minute 43 9 second 52.0 10 weekday 2 11 yearday 192 12 timezone 8:00:00 13 week 28 14 isoweek 28
Dates can be converted from/to Unix epoch time using to action.
Syntax
to-integer <date> to-date <epoch> <date> : a date! value <epoch> : an integer value representing an epoch time
Epoch time are expressed in UTC. If the argument date is not in UTC, it will be converted internally before converting to epoch time.
d: 8-Jul-2017/17:49:27+08:00 to-integer d == 1499507367 to-integer 8-Jul-2017/9:49:27 == 1499507367 to-date to-integer d == 8-Jul-2017/9:49:27
Note that epoch time is not defined beyond the year 2038.
Syntax
to date! <spec> <spec> : a block of values for date fields
The argument block will be converted to a date! value according to the same syntax as for make (see 2.2 [_runtime_creation]). Out of range argument values will result in a normalized date. For a strict conversion from a block, that will error out instead of normalizing, use make.
All comparators can be applied on dates: =, ==, <>, >, <, >=, <=, =?. In addition, min, max and sort are also supported.
Examples
3-Jul-2017/9:41:40+2:00 = 3-Jul-2017/5:41:40-2:00 == true 10/10/2017 < 1/1/2017 == false max 10/10/2017 1/1/2017 == 10-Oct-2017 1/1/1980 =? 1-JAN-1980 == true sort [1/1/2017 5/10/1999 3-Jul-2017/5:41:40-2:00 1/1/1950 1/1/1980/2:2:2] == [1-Jan-1950 1-Jan-1980/2:02:02 5-Oct-1999 1-Jan-2017 3-Jul-2017/5:41:40-02:00]
Supported math operations on dates include:
-
adding or subtracting values from any date field: the result is normalized.
-
adding or subtracting an integer value with a date value: interpreted as a number of days.
-
adding or subtracting a time value with a date value: will add/subtract it to/from the date’s time.
-
subtracting two date values: result is a signed number of days between those two dates.
-
using the
differencefunction on two date values: result is the signed difference, as atime!value, between those two dates.
Examples
20-Feb-1980 + 50 == 10-Apr-1980 20-Feb-1980 + 3 == 23-Feb-1980 20-Feb-1980 - 25 == 26-Jan-1980 20-Feb-1980 + 100 == 30-May-1980 28-Feb-1980 + 20:30:45 == 28-Feb-1980/20:30:45 28-Feb-1980/8:30:00 + 20:30:45 == 29-Feb-1980/5:00:45 d: 20-Feb-1980 d/day: d/day + 50 == 10-Apr-1980 d: 20-Feb-1980 d/month: d/month + 5 == 20-Jul-1980 d: 28-Feb-1980/8:30:00 d/hour: d/hour + 48 == 1-Mar-1980/8:30:00 08/07/2017/10:45:00 - 20-Feb-1980/05:30:0 == 13653 difference 08/07/2017/10:45:00 20-Feb-1980/05:30:0 327677:15:00
The now function returns the operating system’s current date and time (including timezone). All the date path accessors are available to now as refinements, with some additions:
-
/utc: get the date in UTC format. -
/precise: get the time with higher precision (1/60th of a second on Windows, micro-seconds on Unix)
Examples
now == 8-Jul-2017/18:32:25+08:00 now/year == 2017 now/hour == 18 now/month == 7 now/day == 8 now/hour == 18 now/zone == 8:00:00 now/utc == 8-Jul-2017/10:32:25
Syntax
random <date> <date> : a date! value
Description
Returns a randomized date using the argument date as upper limit. If the argument date has no time/timezone component, the resulting date won’t have it either.
Examples
random 09/07/2017 == 18-May-1972 random 09/07/2017 == 13-Aug-0981 random 09/07/2017/12:00:00+8 == 28-Feb-0341/17:57:12+04:00 random 09/07/2017/12:00:00+8 == 13-Dec-1062/5:09:12-00:30