Skip to content

Latest commit

 

History

History
886 lines (692 loc) · 22 KB

date.adoc

File metadata and controls

886 lines (692 loc) · 22 KB

Date! データ型

1. 概要

date! 値はグレゴリオ暦のカレンダー上の日付を表します。dateの値はオプションで時間(time)とタイムゾーンの情報も含みます。dateの中のtimeは24時間表記(オプションのタイムゾーン情報も含む)で表現されます。Redのdateは ISO 8601 の入力フォーマットもサポートします。

Note:

  • date!先発グレゴリオ暦 を1582年まで延長して使用しています。歴史的な、グレゴリオ暦以前の日付を date! 値で表現する場合は注意が必要です。

  • サポートされる日付の範囲は数学的処理のオーバーフローを抑えるため、 1/Jan/-16384 から 31/Dec/16383 までです。入力の場合、実運用の面から 1/Jan/-9999 から 31/Dec/9999 の範囲に減らされます。

2. 生成

date! 値は次の場合に作成されます。リテラル構文を使った場合、実行時に make コンストラクタを使った場合、 to で変換を行った場合です。

2.1. リテラル構文

多くのリテラルフォーマットがサポートされます。これには全ての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>     : 2000年代の年を示す2桁の数字
<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桁の数字(区切り文字なし)

dateリテラルとしてその他にも多くの入力フォーマットが使用できます。範囲外の値(桁数が多かったりフィールドの基準を超えている)の場合はシンタックスエラーになります。表示などのために再びシリアライズされる場合、以下の標準的なフォーマットだけが使用されます。

<dd>-<mon>-<yyyy>
<dd>-<mon>-<yyyy>/<hour>:<min>:<sec>
<dd>-<mon>-<yyyy>/<hour>:<min>:<sec><sign><hour>:<min15>

timeやzoneフィールドがセットされていない場合、その部分は省略されます。負の日付の場合、可読性のために「-」の代わりに「/」が区切り文字として使われます。

Notes:

  • 月が文字で指定された場合、月は英語名として判断され、大文字・小文字は区別しません。

  • 年が2桁の数字(yy)で指定された場合、数値が50より小さければ、2000年代だと判断され、50以上の場合は1900年代と判断されます。

以下はdateの有効な入力値の例です。

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. 実行時の生成

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

Notes:

  • 範囲外の値を引数として渡すとエラーになります。標準化された結果を得るためには、 make ではなく to アクションを使用してください。

  • yearday フィールドは、年が小さい値の場合は置き換え可能です。年は値が100以上で3つ目のフィールドより小さい場合 のみ 1番目になることができます。このルールを満たしていない場合、3番目のフィールドが年だと認識されます。負の年は必ず3番目に位置する必要があります。

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. パスアクセサ

利便性の高いパスアクセサが全ての date! 値のフィールドに提供されます。

3.1. /date

構文
<date>/date
<date>/date: <date2>

<date>  : date!値を参照するwordまたはパス式
<date2> : date!の値

説明

日時フィールドの日付部分(timeとzoneを抜いた部分)を取得または設定します。日付部分は 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> : date!値を参照するwordまたはパス式
<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

3.3. /month

構文
<date>/month
<date>/month: <month>

<date>  : date!値を参照するwordまたはパス式
<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                            ; 月は正常範囲に変換されます。

3.4. /day

構文
<date>/day
<date>/day: <day>

<date> : date!値を参照するwordまたはパス式
<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

3.5. /time

構文
<date>/time
<date>/time: <time>

<date> : date!値を参照するwordまたはパス式
<time> : time!またはnone!の値

説明

日時の時間フィールドを取得または設定します。時間は time! 型の値として返されます。ただし、timeがセットされていない場合やリセット(以下を参照してください)されている場合は none! が返されます。範囲外の引数は正常範囲に変換された値になります。

timeに none! がセットされている場合、timeとzoneフィールドは0になり、表示されなくなります。

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> : date!値を参照するwordまたはパス式
<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

3.7. /minute

構文
<date>/minute
<date>/minute: <minute>

<date>   : date!値を参照するwordまたはパス式
<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

3.8. /second

構文
<date>/second
<date>/second: <second>

<date>   : date!値を参照するwordまたはパス式
<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

3.9. /zone

構文
<date>/zone
<date>/zone: <zone>

<date> : date!値を参照するwordまたはパス式
<zone> : time!またはinteger!値

説明

日時のタイムゾーンフィールドを取得または設定します。タイムゾーンは -16:00 から +15:00 までの time! 値で返されます。 /zone を使ってタイムゾーンを設定すると、zoneフィールドだけが変更され、timeはそのままになります。範囲外の引数は正常範囲に変換された値になります。

タイムゾーンに 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>     : date!値を参照するwordまたはパス式
<timezone> : integer!、time!またはpair!の値

説明

日時のタイムゾーンフィールドを取得または設定します。タイムゾーンは -16:00 から +15:00 までの time! 値で返されます。タイムゾーンを /timezone でセットすると、timeとzoneフィールドの両方が更新され、古い値と等価な新しいzoneでの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>    : date!値を参照するwordまたはパス式
<yearday> : integer!値

説明

日時がその年の何日目かを取得します。1月1日が1で始まります。日にちは整数値で返されます。年の日にちをセットするために使われた場合、その日数に合うように日にちが再計算されます。範囲外の引数は正常範囲に変換されます。

Note:

  • /yearday とエイリアスとして /julian も使用可能です。これは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                  ; うるう年

d: 31-dec-2017
== 31-Dec-2017
d/yearday: 366
== 366
d
== 1-Jan-2018

3.12. /weekday

構文
<date>/weekday
<date>/weekday: <day>

<date>    : date!値を参照するwordまたはパス式
<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

3.13. /week

構文
<date>/week
<date>/week: <day>

<date> : date!値を参照するwordまたはパス式
<week> : integer!値

説明

週の番号を日用的な曜日の定義(日曜日が最初で、最初の週は1月1日に始まります)に従って取得します。範囲は1がその年の最初の週で53までです。週の番号をセットするために使用された場合、日にちはその週の最初の日(日曜日)になるように再計算されます。範囲外の引数は正常範囲に変換されます。

Note:

  • 日用的な曜日の定義では一年の最初と最後の週は1日から7日のいずかになります。年をまたぐ精確な週の計算を行いたい場合、 /isoweek アクセサを使用してください。

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>    : date!値を参照するwordまたはパス式
<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

3.15. インデックスアクセス

日時のフィールドにアクセスするには、wordを使うのに加えて、パス式の中で整数のインデックスを使用する方法もあります。

<date>/<index>

<date>  : date!値を参照するwordまたはパス式
<index> : 日時フィールドを参照するinteger!値

このようなインデックスアクセスでフィールドの取得、設定を行うことができます。以下はフィールド名との対応表です。

インデックス フィールド名

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を使った日時フィールドへのアクセス

パスを使わずに日時フィールドへアクセスすることも可能であり、これは特定のケースでは有用です。これには pick を使用します。

構文
pick <date> <field>

<date>  : date!値
<field> : integer!値

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

4. 値の変換

4.1. UNIX時間

日時は UNIX時間 との間で to アクションを使って相互変換できます。

構文
to-integer <date>
to-date <epoch>

<date>  : date!値
<epoch> : UNIX時間を表すinteger!値

UNIX時間はUTCで表現されます。引数がUTCでない場合、UNIX時間に変換される前に内部的に変換されます。

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

UNIX時間は2038年を超える年は未定義であることに注意してください。

4.2. ブロックから日時への変換

構文
to date! <spec>

<spec> : 日時フィールドを持つブロックの値

引数のブロックは make と同じシンタックス(2.2章 実行時の生成 を参照してください)に従って date! 値に変換されます。範囲外の引数は正常範囲に変換されます。正常値への変換ではなくエラーとする、ブロックからの厳密な変換が必要な場合、 make を使用してください。

5. 比較

右記の全ての比較演算子が日時に使用できます。=, ==, <>, >, <, >=, <=, same? 加えて、minmaxsort もサポートされます。

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. 算術演算

サポートされる日時への数学的計算は以下です。

  • 日時フィールドへの加算および減算:結果は正常範囲に変換されます。

  • 日時の値への整数値の加算および減算:日数として解釈されます

  • 日時値へのtime値の加算および減算:dateの時間からその分を加算・減算した値になります。

  • 2つの日時値の減算:結果は2つの日時間の符号付きの数値になります。

  • 2つの日時値への difference 関数の使用:結果は2つの日時の間の符号付きの 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

7. 現在日時の取得

now 関数はOS上の現在日時(タイムゾーンを含む)を返します。全ての日時関連のパスアクセサが now 関数でリファインメントとして使用できます。また以下の追加のリファインメントも使用できます。

  • /utc: UTCフォーマットで日時を取得します

  • /precise: より高い精度(Windowsでは60分の1秒の制度、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

8. その他の日時に関する関数

8.1. Random

構文
random <date>

<date> : date!値

説明

引数の日時を上限にランダムな日時を返します。引数の日時がtimeとtimezoneが指定されていない場合、結果の日時にもtimeとtimezoneは付きません。

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