Skip to content

Latest commit

 

History

History
926 lines (685 loc) · 20.1 KB

date.adoc

File metadata and controls

926 lines (685 loc) · 20.1 KB

Date! 日期数据类型

1. 摘要 (Abstract)

Date! 值表示公历日期。 一个date变量值,也可以包含可选的时间和时区信息。 日期的时间以24小时格式表示 (包括可选的时区信息). Red日期类型也广泛支持 ISO 8601 输入格式。

Note:

  • date! 使用 proleptic Gregorian calendar,可延伸到1582年以后。 在使用 date! 日期表示历史时应注意前公历的日期!(原文:Care should be taken when trying to represent historical, pre-Gregorian dates using date! values.)

  • 支持的日期范围从 1/Jan/-1638431/Dec/16383, 通过数学运算进行换算。 在输入时,出于实际情况,该范围简化为从`1/Jan/-9999` 到 31/Dec/9999。(原文: that range is reduced to 1/Jan/-9999 to 31/Dec/9999 for practical reasons.)

2. 创建 (Creation)

Date! 变量可以使用字面语法创建, 或者在运行时使用`make`构造函数或`to`转换为日期类型。

2.1. 字面语法(Literal syntax)

支持多种不同的字面语法格式, 包括所有Rebol日期格式和大多数ISO日期标准。

<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>    : 分隔符号使用 `-` 或 `/`
<yyyy>   : 3 或 4 位数字代表年份 (4 位数字表示国际标准日期-ISO dates)
<yy>     : 2 位数字表示的年份,代表相对于2000年
<m>      : 1或2位数字代表月份
<mm>     : 2位数字代表月份
<mon>	 : 3个字母代表月份
<month>  : 月份的英语全名
<d>      : 一个数字表示一周中的某一天 (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位数字,表示小时,分和秒(无分隔符)

(原文:Many different input formats for literal dates are accepted. (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>

当时间和/或区域字段未设置时,它们会被省略。 对于负日期值,使用 / 分隔符而不是 - 来提高可读性。

Notes:

  • 当使用字母指定一个月时,使用其英文名称表示该月份,并且不区分大小写。

  • 当一个年份仅用两位数字 (yy)指定时:如果yy<50,则被解释为 '20yy' 年,否则解释为 '19yy' 年。

有效的日期输入例子如下: (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

2.2. 运行时创建 (Runtime creation)

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! 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

Notes:

  • 超出范围的参数值将导致错误。 为规范化结果, 使用 to 替代掉 make.

  • yearday 字段位置可以互换, 但只适用于低年值。 仅*当年份值>=100且小于第三个字段的值时可以将年份放在第一个位置。 (原文:The year can be used in first position *only if its value is >= 100 and less than the value of the third field.) 当这个规则不满足的时候, 第三个字段被认为是年份。 指定负年数永远都是用第三个位置。

例子

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

3. 路径访问器(Path accessors)

路径访问器提供了一种便捷的方式来获取和设置所有日期值( date! value)字段。

3.1. /date

语法

<date>/date
<date>/date: <date2>

<date>  : a word or path expression referring to a date! value
<date2> : a date! value

描述

获取或设置日期的日期字段(不包括时间和区域)。 日期返回为 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

3.2. /year

语法

<date>/year
<date>/year: <year>

<date> : a word or path expression referring to a date! value
<year> : an integer! value

描述

获取或设置日期的年份字段。 年数返回为整数。超出范围的参数值会返回一个标准化日期。

例子

d:  now
== 10-Jul-2017/22:46:22-06:00
d/year: 10000
== 10000
d
== 10-Jul-10000/22:46:22-06:00
d/year: 32768
== 32768
d
== 10/Jul/-32768/22:46:22-06:00     ; Note wrap on overflow

3.3. /month

语法

<date>/month
<date>/month: <month>

<date>  : a word or path expression referring to a date! value
<month> : an integer! value

描述

获取或设置日期的月份字段。 月数返回为整数。 超出范围的参数值会返回一个标准化日期。

例子

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

3.4. /day

语法

<date>/day
<date>/day: <day>

<date> : a word or path expression referring to a date! value
<day>  : an integer! value

描述

获取或设置日期的日期字段。 天数返回为整数。 超出范围的参数值会返回一个标准化日期。

例子

 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

3.5. /time

语法

<date>/time
<date>/time: <time>

<date> : a word or path expression referring to a date! value
<time> : a time! or none! value

描述

获取或设置日期的时间字段。 返回 time! 值, 或返回 none! 值如果时间未设定, 或已重置(见下文)。 超出范围的参数值会返回一个标准化日期。

如果时间设置为 none! 值, 时间和区域字段设置为零,字段值将不会被显示。

例子

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

3.6. /hour

语法

<date>/hour
<date>/hour: <hour>

<date> : a word or path expression referring to a date! value
<hour> : an integer! value

描述

获取或设置日期的小时数字段。 小时数返回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

3.7. /minute

语法

<date>/minute
<date>/minute: <minute>

<date>   : a word or path expression referring to a date! value
<minute> : an integer! value

描述

获取或设置日期的分钟字段。 分钟返回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

3.8. /second

语法

<date>/second
<date>/second: <second>

<date>   : a word or path expression referring to a date! value
<second> : an integer! or float! value

描述

获取或设置日期的秒数字段。 秒数返回为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

3.9. /zone

语法

<date>/zone
<date>/zone: <zone>

<date> : a word or path expression referring to a date! value
<zone> : a time! or integer! value

描述

获取或设置日期的时区字段。 时区在-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

3.10. /timezone

语法

<date>/timezone
<date>/timezone: <zone>

<date>     : a word or path expression referring to a date! value
<timezone> : an integer!, time! or pair! value

描述

获取或设置日期的时区字段。 时区在-16:00和+15:00之间返回为`time!值。 使用/timezone`设置时区将会修改时间和时区, 保持新时间相当于新区的旧时间。 超出范围的参数值会返回一个标准化日期。 当用 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

Note:

  • 设定 /timezone 为 0 将会把时间设置为 UTC 格式。

3.11. /yearday

语法

<date>/yearday
<date>/yearday: <day>

<date>    : a word or path expression referring to a date! value
<yearday> : an integer! value

描述

获取一年中的天数,从1月1日开始。 返回整数。 当用于设置一年中的日期时,重新计算日期以匹配当天。 超出范围的参数值会返回一个标准化日期。

Note:

  • 另一个 /julian 别名 for /yearday 也可以用, 与Rebol兼容。

例子

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

3.12. /weekday

语法

<date>/weekday
<date>/weekday: <day>

<date>    : a word or path expression referring to a date! value
<weekday> : an integer! value

描述

获取周的天数, 从星期一(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

3.13. /week

语法

<date>/week
<date>/week: <day>

<date> : a word or path expression referring to a date! value
<week> : an integer! value

描述

获取周数(周从星期日开始,第一周从1月1日开始), 从年的第1个星期直到到第53个。 用于设置周数时,重新计算日期以匹配该周(星期日)的第一天。 超出范围的参数值会返回一个标准化日期。

Note:

  • 休闲周定义允许一年中的第一个和最后几个星期是部分周,范围从1天到7天,对于精确周计算,请使用`/isoweek` 来获取。 原文:The casual week definition allows first and last weeks of the year to be partial weeks, ranging from 1 day to 7 days. For accurate week calculations across years, use the /isoweek accessor.

例子

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

3.14. /isoweek

语法

<date>/isoweek
<date>/isoweek: <day>

<date>    : a word or path expression referring to a date! value
<isoweek> : an integer! value

描述

获取周数使用 国际标准8601文件的(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

3.15. 序列访问器 Ordinal accessors

除了使用单词访问日期字段, 也可以在路径表达式中使用整数索引:

<date>/<index>

<date>  : a word or path expression referring to a date! value
<index> : an integer! value referring to a date field.

这样的序列访问器可以用于获取或设置字段。 下表给出了对应的字段名称

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

3.16. 使用Pick访问日期字段 Accessing date fields using Pick

在某些情况下可以不使用路径访问日期字段。 pick 可以对日期使用。

语法

pick <date> <field>

<date>  : a date! value
<field> : an integer! value

整数参数表示日期的顺序访问器,参见上面的"序列访问器"表。

例子

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

4. 转换 Conversions

4.1. 世纪时间 Epoch time

日期可以用 to 操作互换成 Unix 世纪时间 .

语法

to-integer <date>
to-date <epoch>

<date>  : a date! value
<epoch> : an integer value representing an epoch time

世纪时间,以UTC表示,如果参数不是用UTC,它将在转换为时代之前在内部转换。 原文: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

请注意,2038年之后的世纪时间没有定义。 原文:Note that epoch time is not defined beyond the year 2038.

4.2. 块转换为日期 Block to date

语法

to date! <spec>

<spec> : a block of values for date fields

根据与`make`相同的语法,to`将参数块将被转换为 `date! 值 (see 2.2 运行时创建 Runtime creation). 超出范围的参数值会返回一个标准化日期。 对于一个块的严格转换,这将会产生错误而不是标准化,使用`make`。

5. 对比 Comparisons

所有可以应用于日期的对比有: =, ==, <>, >, <, >=, <=, same?. 此外, min, maxsort 也支持。

例子

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]

6. 运算 Arithmetic

可对日期进行的数学运算包括:

  • 从任何日期字段添加或减去值:结果被标准化。 原文: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 from the date’s time.

  • 减去两个日期值(感觉应该是两个日期相减):结果是这两个日期之间签署的天数。 原文:subtracting two date values: result is a signed number of days between those two dates.

  • 使用`difference`函数对比两个日期:返回`time!值,内容是两个日期之间差异。 原文:using the `difference function on two date values: result is the signed difference, as a time! value, between those two dates.

例子

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

7. 获取当前日期 Getting the current date

`now` 函数返回操作系统的当前日期和时间(包括时区)。 所有的日期路径访问器都可用于 `now` 作为细化,还有一些补充:
  • /utc: 获取UTC格式日期。

  • /precise: 以更高的精度获得时间 (Windows上的1/60秒,Unix上的微秒:micro-seconds)

例子

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

8.1. 随机(Random)

语法

random <date>

<date> : a date! value

描述

使用参数日期作为上限,返回一个随机日期。 如果参数日期没有时间/时区组件,则产成的日期也没有。

例子

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