date!
值可以使用字面语法创建,或者在运行时使用 make
构造函数创建,或用 to
转换到日期类型。
它支持多种不同的字面语法格式,包括所有的 Rebol 日期格式和大多数的 ISO 日期标准。
<date>/<time>
<date>/<time><zone>
<date>T<time>
<date>T<time>Z
<date>T<time><zone>
<date> 格式:
<yyyy><sep><mmm><sep><dd>
<dd><sep><mmm><sep><yyyy>
<dd><sep><mmm><sep><yy>
当后接 T 时附加的 <date> 格式:
<yyyy><mm><dd>
<yyyy>-W<ww>
<yyyy>-W<ww>-<d>
<yyyy>-<ddd>
<mmm> 格式(月份):
<m>
<mon>
<month>
<time> 格式:
<hour>:<min>:<sec>
<hour>:<min>:<sec><zone>
<hhmmss>
<hhmmss><zone>
<hhmmss>.<dec>
<hhmmss>.<dec><zone>
<hhmm>
<hhmm><zone>
<zone> 格式(时区):
<sign><hour>
<sign><hour>:<min15>
<sign><hhmm>
<sec> 格式(秒):
<ss>
<ss>.<dec>
<sep> : `-` 或 `/`
<yyyy> : 3 或 4 位数字,代表年份(4 位数字表示 ISO 日期)
<yy> : 2 个数字代表相对于 2000 年的年份
<m> : 1 或 2 位数字,代表月份
<mm> : 2 位数字,代表月份
<mon> : 3 位字母,代表月份的开始
<month> : 月份的英文全名
<d> : 1 位数字,代表星期(1 到 7)
<dd> : 1 或 2 位数字,表示日
<ddd> : 3 位数字,代表年中的某一天
<ww> : 2 位数字,代表年中的某一周
<time> : time! 值
<hour> : 1 或 2 位数字,代表小时
<min> : 1 或 2 位数字,代表分钟
<ss> : 1 或 2 位数字,代表秒
<dec> : 秒的小数
<sign> : `+` 或 `-` 字符(不能省略)
<min15> : 和 <min> 相同但会被舍入为 15 的倍数
<hhmm> : 4 位数字,表示小时和分钟(无分隔符)
<hhmmss> : 6 位数字,表示小时、分种和秒(无分隔符)
日期字面值可以接受许多不同的输入格式。超出范围的值(超过指定的数字位数或不符合字段的规范)将产生语法错误。当再次序列化(例如用于显示)时,仅使用以下标准格式:
<dd>-<mon>-<yyyy>
<dd>-<mon>-<yyyy>/<hour>:<min>:<sec>
<dd>-<mon>-<yyyy>/<hour>:<min>:<sec><sign><hour>:<min15>
当 time
和/或 zone
字段没有被设置时,它们会被省略。对于负的日期值,使用 /
分隔符取代 -
分隔符以提高可读性。
注意
|
|
有效的日期输入例子:
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> <hour> <minute> <second>]
make date! [<day> <month> <year> <hour> <minute> <second> <zone>]
<year> : integer! 值
<month> : integer! 值
<day> : integer! 值
<time> : time! 值
<zone> : integer! , time! 或 pair! 值
<hour> : integer! 值
<minute> : integer! 值
<second> : integer! 值
注意
|
|
例
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 不是有效的日期
make date! [100 12 32]
*** Script Error: cannot MAKE/TO date! from: [100 12 32]
*** Where: make
; 第一个字段 < 100,所以不被认为是年份
make date! [99 12 31]
*** Script Error: cannot MAKE/TO date! from: [99 12 31]
*** Where: make
路径访问器提供了一种便捷的方式来获取和设置所有 date!
值字段。
语法
<date>/date
<date>/date: <date2>
<date> : 引用 date! 值的单词或路径表达式
<date2> : date! 值
描述
获取或设置日期的日期字段(不包括时间和区域),返回作为 date!
值的日期。
例
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
语法
<date>/year
<date>/year: <year>
<date> : 引用 date! 值的单词或路径表达式
<year> : integer! 值
描述
获取或设置日期的年份字段,返回作为整数的年份。超出取值范围的参数值会产生一个正规化的日期。
例
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 ; 注意超过 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
语法
<date>/month
<date>/month: <month>
<date> : 引用 date! 值的单词或路径表达式
<month> : integer! 值
描述
获取或设置日期的月份字段,返回作为整数的月份。超出取值范围的参数值会产生一个正规化的日期。
例
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 ; 注意折返到了下一年
d/month
== 1 ; 月份现在被正规化了
语法
<date>/day
<date>/day: <day>
<date> : 引用 date! 值的单词或路径表达式
<day> : integer! 值
描述
获取或设置日期的日字段,返回作为整数的日。超出取值范围的参数值会产生一个正规化的日期。
例
d: 1-jan-2017
== 1-Jan-2017
d/day: 32
== 32
d
== 1-Feb-2017
d/day: 0 ; 注意 0 起的作用,以使日期数学合理
== 0
d
== 31-Jan-2017
语法
<date>/time
<date>/time: <time>
<date> : 引用 date! 值的单词或路径表达式
<time> : time! 或 none! 值
描述
获取或设置日期的时间字段,返回作为 time!
值的时间,或者如果时间没有被设置或已经被重置(见下文),就返回 none!
值。超出取值范围的参数值会产生一个正规化的日期。
如果时间被设置为 none!
值,则 time
和 zone
字段将被设置为零,并且不再会被显示出来。
例
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
语法
<date>/hour
<date>/hour: <hour>
<date> : 引用 date! 值的单词或路径表达式
<hour> : integer! 值
描述
获取或设置日期的小时字段,返回 0 到 23 之间的作为整数值的小时。超出取值范围的参数值会产生一个正规化的日期。
例
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
语法
<date>/minute
<date>/minute: <minute>
<date> : 引用 date! 值的单词或路径表达式
<minute> : integer! 值
描述
获取或设置日期的分钟字段,返回 0 到 59 之间的作为整数值的分钟。超出取值范围的参数值会产生一个正规化的日期。
例
== 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
语法
<date>/second
<date>/second: <second>
<date> : 引用 date! 值的单词或路径表达式
<second> : integer! 或 float! 值
描述
获取或设置日期的秒数字段,返回为 0 到 59 之间的作为 integer!
或 float!
值的秒数。超出取值范围的参数值会产生一个正规化的日期。
例
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
语法
<date>/zone
<date>/zone: <zone>
<date> : 引用 date! 值的单词或路径表达式
<zone> : time! 或 integer! 值
描述
获取或设置日期的时区字段,返回在 -16:00 与 +15:00 之间的作为 time!
值的时区。使用 /zone
设置时区将仅改变该字段,时间会保持不变。超出取值范围的参数值会产生一个正规化的日期。
当用 integer!
参数设置时区时,该参数表示分钟被设置为 0 的小时数。
时区的分钟数的粒度为 15,不遵照粒度的值将被向下舍入到最靠近的 15 分钟的倍数。
例
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
语法
<date>/timezone
<date>/timezone: <timezone>
<date> : 引用 date! 值的单词或路径表达式
<timezone> : integer! , time! 或 pair! 值
描述
获取或设置日期的时区字段,返回在 -16:00 与 +15:00 之间的作为 time!
值的时区。使用 /zone
设置时区将改变时间和区域两个字段,使新时间保持与在新区域内的旧时间相等。超出取值范围的参数值会产生一个正规化的日期。
当用 integer!
参数设置时区时,该参数表示分钟被设置为 0 的小时数。
时区的分钟数的粒度为 15,不遵照粒度的值将被向下舍入到最靠近的 15 分钟的倍数。
例
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
注意
|
|
语法
<date>/yearday
<date>/yearday: <day>
<date> : 引用 date! 值的单词或路径表达式
<yearday> : integer! 值
描述
获取日期当天在当年中的天数,从 1 月 1 日开始计为 1,返回作为整数的天数。当用于设置当年中的当天天数时,该日期会被重新计算以匹配那一天。超出取值范围的参数值会产生一个正规化的日期。
注意
|
|
例
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 ; 闰年
d: 31-dec-2017
== 31-Dec-2017
d/yearday: 366
== 366
d
== 1-Jan-2018
语法
<date>/weekday
<date>/weekday: <day>
<date> : 引用 date! 值的单词或路径表达式
<weekday> : integer! 值
描述
获取星期数值,取值范围为从星期一的 1 到星期天的 7。当用于设置星期时,该日期会被重新计算以匹配相对于这周的那一天。超出取值范围的参数值会产生一个正规化的日期。
例
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
语法
<date>/week
<date>/week: <day>
<date> : 引用 date! 值的单词或路径表达式
<week> : integer! 值
描述
获取使用非正式周定义的周数(周从星期日开始,第一周从 1 月 1 日开始),取值范围为从年中第一个星期的 1 到 53。当用于设置周数时,该日期会被重新计算以匹配那周的第一天(星期日)。超出取值范围的参数值会产生一个正规化的日期。
注意
|
|
例
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
语法
<date>/isoweek
<date>/isoweek: <day>
<date> : 引用 date! 值的单词或路径表达式
<isoweek> : integer! 值
描述
获取使用 ISO 8601 周定义的周数,取值范围为从年中第一个星期的 1,到 52(或者某些年是 53)。当用于设置周数时,该日期会被重新计算以匹配那周的第一天(星期一)。超出取值范围的参数值会产生一个正规化的日期。
例
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
除了使用单词来访问日期的字段,也可以在路径表达式中使用整数索引:
<date>/<index>
<date> : 引用 date! 值的单词或路径表达式
<index> : 指向日期字段的 integer! 值
这样的序数访问器可以用于获取或设置字段。下表给出了对应的字段名称
索引 | 名称 |
---|---|
1 |
|
2 |
|
3 |
|
4 |
|
5 |
|
6 |
|
7 |
|
8 |
|
9 |
|
10 |
|
11 |
|
12 |
|
13 |
|
14 |
|
可以不使用路径来访问日期字段,这在某些情况下更为便捷,可以对日期使用 pick
。
语法
pick <date> <field>
<date> : date! 值
<field> : integer! 值
整数参数代表用于日期的序数访问器,参照上面的 “序数访问器” 表格。
例
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
日期可以用 to
动作与 Unix 新纪元时间互相转换。
语法
to-integer <date>
to-date <epoch>
<date> : date! 值
<epoch> : 代表新纪元时间的整数值
新纪元时间,以 UTC 时区表示。如果日期参数不在 UTC 时区,它会在转换为新纪元时间之前被内部地转换到 UTC 时区。
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
注意
|
2038 年之后的新纪元时间是未定义的。 |
语法
to date! <spec>
<spec> : 用于日期字段的内含值的区块
参数区块会按照跟 make
(参考 2.2 运行时创建)一样的语法被转换为 date!
值。超出取值范围的参数值会产生正规化的日期。若要从区块进行会产生错误而不会被正规化的严格转换,请使用 make
。
所有可以应用于日期的比较有:=
、==
、<>
、>
、<
、>=
、<=
、same?
。此外,还支持 min
、max
和 sort
。
例
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
same? 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]
可对日期进行的数学操作包括:
-
加减任何日期字段中的值:结果将被正规化。
-
用日期值跟整数值相加减:该整数会被解释为天数。
-
用日期值跟时间值相加减:将把日期的时间增加/减少该时间。
-
两个日期相减:结果是这两个日期相隔的有符号天数。
-
以两个日期为参数调用
difference
:结果是作为time!
值的这两个日期之间的有符号的差。
例
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
now
函数返回操作系统的当前日期和时间(包括时区)。所有的日期路径访问器都可作为修饰词用于 now
,另外还有一些附加的:
-
/utc
:获取 UTC 格式的日期。 -
/precise
:以更高的精度获得时间(在 Windows 上为 1/60 秒,在 Unix 上为微秒)。
例
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