この SRFI は現在「確定」の状態である。SRFI の各状態の説明については ここ を参照せよ。 この SRFI に関する議論については メーリングリストのアーカイブ を参照せよ。
~D
の誤りを修正: 2003-05-30日付は、グレゴリオ暦と、 (ナノ秒精度の) 24 時間形式の時刻と、 UTC からのタイムゾーン オフセットで表現する。 時刻と日付の変換関数や、 日付の文字列表現を読み書きする手続きを提供する。
時刻 オブジェクトは、他のデータ型とは異なる型であり、 何らかの標準時システムにおける時刻や時間差を表す。 標準時システムとしては以下のものがある:
時刻オブジェクトは、次の 3 つの要素で構成される。
TIME-TAI
,
TIME-UTC
, TIME-MONOTONIC
,
TIME-THREAD
, TIME-PROCESS
,
TIME-DURATION
は、それぞれの時刻システムを表す。
独自の標準時システムを実装する場合は、そのシンボルを提供すべきである。
日付オブジェクトは、他のデータ型とは異なる型であり、 グレゴリオ暦の時刻とタイムゾーンを表す。 日付は変更不可能 (immutable) なオブジェクトである。 日付は以下の要素で構成される。
ユリウス日 は -4714-11-24T12:00:00Z (-4714年11月24日の正午, UTC) からの日数を実数で表現する時刻表現である。
準ユリウス日 は 1858-11-17T00:00:00Z (1858年11月17日の夜中, UTC) からの日数を実数で表現する時刻表現である。
以下の定数を提供しなければならない。
time-duration
time-monotonic
time-process
time-tai
time-thread
time-utc
以下の手続きを提供しなければならない。
current-date
[tz-offset] -> date
current-julian-day
-> jdn
current-modified-julian-day
-> mjdn
current-time
[time-type] -> time
time-type
の時刻システムで返す。
デフォルトの時刻タイプは TIME-UTC
である。
time-resolution
[time-type] -> integer
time-type
の時刻システムの解像度をナノ秒単位で返す。
デフォルトの時刻タイプは TIME-UTC
である。
以下の手続きを提供しなければならない。
make-time
type nanosecond second -> time
time?
object -> boolean
#t
を返し、
そうでなければ #f
を返す。
time-type
time -> time-type
time-nanosecond
time -> integer
time-second
time -> integer
set-time-type!
time time-type
set-time-nanosecond!
time integer
set-time-second!
time integer
copy-time
time1 -> time2
時刻の比較手続きでは、比較する時刻オブジェクトが同じ時刻タイプをもたなければらない。
異なる時刻タイプをもつ時刻オブジェクトに対して
比較手続きを呼び出すことはエラーである。
時刻を表す時刻システム (TIME-TAI
や TIME-UTC
)
に対しては、比較の意味を (括弧外の) 通常の文章で説明している。
時間差を表す時刻システム (TIME-DURATION
や TIME-CPU
)
に対しては、比較の意味を括弧内で説明している。
以下の手続きを提供しなければならない。
time<=?
time1 time2 -> boolean
#t
を返し、そうでなければ #f
を返す。
time<?
time1 time2 -> boolean
#t
を返し、そうでなければ #f
を返す。
time=?
time1 time2 -> boolean
#t
を返し、そうでなければ #f
を返す。
time>=?
time1 time2 -> boolean
#t
を返し、そうでなければ #f
を返す。
time>?
time1 time2 -> boolean
#t
を返し、そうでなければ #f
を返す。
以下の手続きを提供しなければならない。
time-difference
time1 time2 -> time-duration
TIME-DURATION
を返す。
time1 と time2 の時刻タイプが異なる場合は、エラーである。
新しい時刻オブジェクトを作成して返す。
time-difference!
time1 time2 -> time-duration
TIME-DURATION
を返す。
time1 と time2 の時刻タイプが異なる場合は、エラーである。
time1 を破壊的に使用して戻り値の TIME-DURATION
オブジェクトを返してもよい。
add-duration
time1 time-duration -> time
add-duration!
time1 time-duration -> time
subtract-duration
time1 time-duration -> time
subtract-duration!
time1 time-duration -> time
日付オブジェクトは、いったん作成すると変更することはできない。 以下の手続きを提供しなければならない。
make-date
nanosecond second minute hour day month year zone-offset -> date
date?
date -> boolean
#t
を返し、そうでなければ #f
を返す。
date-nanosecond
date -> integer
date-second
date -> integer
date-minute
date -> integer
date-hour
date -> integer
date-day
date -> integer
date-month
date -> integer
date-year
date -> integer
date-zone-offset
date -> integer
date-year-day
date -> integer
date-week-day
date -> integer
date-week-number
date day-of-week-starting-week -> integer
date->julian-day
date -> jd
date->modified-julian-day
date -> mjd
date->time-monotonic
date -> time-monotonic
date->time-tai
date -> time-tai
date->time-utc
date -> time-utc
julian-day->date
jd [tz-offset] -> date
julian-day->time-monotonic
jd -> time-monotonic
julian-day->time-tai
jd -> time-tai
julian-day->time-utc
jd -> time-utc
modified-julian-day->date
mjd [tz-offset] -> date
modified-julian-day->time-monotonic
mjd -> time-monotonic
modified-julian-day->time-tai
mjd -> time-tai
modified-julian-day->time-utc
mjd -> time-utc
time-monotonic->date
time-monotonic [tz-offset] -> date
time-monotonic->julian-day
time-monotonic -> jd
time-monotonic->modified-julian-day
time-monotonic -> mjd
time-monotonic->time-tai
time-monotonic -> time-tai
time-monotonic->time-tai!
time-monotonic -> time-tai
time-monotonic->time-utc
time-monotonic -> time-utc
time-monotonic->time-utc!
time-monotonic -> time-utc
time-tai->date
time-tai [tz-offset] -> date
time-tai->julian-day
time-tai -> jd
time-tai->modified-julian-day
time-tai -> mjd
time-tai->time-monotonic
time-tai -> time-monotonic
time-tai->time-monotonic!
time-tai -> time-monotonic
time-tai->time-utc
time-tai -> time-utc
time-tai->time-utc!
time-tai -> time-utc
time-utc->date
time-utc [tz-offset] -> time-utc
time-utc->julian-day
time-utc -> jd
time-utc->modified-julian-day
time-utc -> mjd
time-utc->time-monotonic
time-utc -> time-monotonic
time-utc->time-monotonic!
time-utc -> time-monotonic
time-utc->time-tai
time-utc -> time-tai
time-utc->time-tai!
time-utc -> time-tai
date->string
date [format-string] -> string
string->date
input-string template-string -> date
Ch | 変換する文字列 |
---|---|
~~ | リテラルの ~ |
~a | ロケール依存の曜日の省略名 (Sun...Sat) |
~A | ロケール依存の曜日の正式名 (Sunday...Saturday) |
~b | ロケール依存の月の省略名 (Jan...Dec) |
~B | ロケール依存の月の正式名 (January...December) |
~c | ロケール依存の日付と時刻 (たとえば "Fri Jul 14 20:28:42-0400 2000") |
~d | 月の日。0 で 2 桁にパディング。 (01...31) |
~D | 日付 (mm/dd/yy) |
~e | 月の日。スペースでパディング ( 1...31) |
~f | 秒+秒の端数。ロケール依存の小数点で区切られる (たとえば 5.2)。 |
~h | ~b に同じ |
~H | 時。24 時間形式で、0 で 2 桁にパディング (00...23) |
~I | 時。12 時間形式で、0 で 2 桁にパディング (01...12) |
~j | 年の日。0 でパディング。 |
~k | 時。24 時間形式で、スペースでパディング ( 0...23) |
~l | 時。12 時間形式で、スペースでパディング ( 1...12) |
~m | 月。0 で 2 桁にパディング (01...12) |
~M | 分。0 で 2 桁にパディング (00...59) |
~n | 改行 |
~N | ナノ秒。0 でパディング。 |
~p | ロケール依存の AM または PM |
~r | 時刻。12 時間形式。"~I:~M:~S ~p" に同じ。 |
~s | エポックからの経過秒数 (UTC) |
~S | 秒。0 で 2 桁にパディング (00...60) |
~t | 水平タブ |
~T | 時刻。24 時間形式。"~H:~M:~S" に同じ。 |
~U | 年の週。日曜日が週の最初の日となる。 (00...53) |
~V | 年の週。月曜日が週の最初の日となる。 (01...52) |
~w | 曜日 (0...6) |
~W | 年の週。月曜日が週の最初の日となる。 (01...52) |
~x | 年の週。月曜日が週の最初の日となる。 (00...53) |
~X | ロケール依存の日付表現。たとえば "07/31/00" |
~y | 年の下 2 桁 (00...99) |
~Y | 年 |
~z | RFC-822 スタイルのタイムゾーン |
~Z | シンボル タイムゾーン (未実装) |
~1 | ISO-8601 year-month-day 形式 |
~2 | ISO-8601 hour-minute-second-timezone 形式 |
~3 | ISO-8601 hour-minute-second 形式 |
~4 | ISO-8601 year-month-day-hour-minute-second-timezone 形式 |
~5 | ISO-8601 year-month-day-hour-minute-second 形式 |
表 1: DATE->STRING の変換指定子 | |
Ch | スキップ先 | 読み取る内容 | 設定 |
---|---|---|---|
~~ | 任意 | リテラル ~ を読み取る | なし |
~a | char-alphabetic? | ロケール依存の曜日の省略名 | なし |
~A | char-alphabetic? | ロケール依存の曜日の完全名 | なし |
~b | char-alphabetic? | ロケール依存の月の省略名 | なし |
~B | char-alphabetic? | ロケール依存の月の完全名 | なし |
~d | char-numeric? | 月の日 | date-day |
~e | 任意 | 月の日。スペースでパディング | date-day |
~h | char-alphabetic? | ~b に同じ | なし |
~H | char-numeric? | 時 | date-hour |
~k | 任意 | 時。スペースでパディング | date-hour |
~m | char-numeric? | 月 | date-month |
~M | char-numeric? | 分 | date-minute |
~S | char-numeric? | 秒 | date-second |
~y | 任意 | 2 桁の年 | date-year (50 年以内) |
~Y | char-numeric? | 年 | date-year |
~z | 任意 | タイムゾーン | date-zone-offset |
Table 2: STRING->DATE の変換指定子 | |||
CURRENT-TIME
の値を取得するための
システム固有の方法がなくてはならない。
これを実装する場合、GNU C の関数
gettimeofday
を使うとよいだろう。
TAI と UTC の差異は決定論的ではなく、 TAI 時刻を取得するための方法を提供しなければならない。 参照実装では、米国海軍観測所の時刻サービスが提供している閏秒テーブル (ftp://maia.usno.navy.mil/ser7/tai-utc.dat から入手できる) を読み取るための手続きを用意した。
この実装では
「SRFI 6: 基本的な文字列ポート」
を使用している。また error
手続きの存在を仮定している。
それから
「SRFI 8: receive による多重値の束縛」
も使用している。
この receive
構文は次のようにして容易に実装できる。
(define-syntax receive (syntax-rules () ((receive formals expression body ...) (call-with-values (lambda () expression) (lambda formals body ...)))))
参照実装には TAI-UTC.DAT リーダーが含まれている。
参照実装は MzScheme で実装した。
MzScheme は current-seconds
手続きを提供しており、
これは 1970-01-01T00:00:00Z+00:00 からの経過秒数 (UTC) を返す。
また current-milliseconds
手続きも提供しており、
これは、モノトニックなタイムクロックを返す。
この2つを組み合わせることで、
(current-time time-utc)
を実装している。
この実装では、モノトニック時刻は TAI 時刻と同じである。
TAI と UTC の差異は閏秒テーブルにより補正される。
国際地球回転観測事業 (IERS: International Earth Rotation Service)
によると、2000年12月には閏秒はないだろうとのことだ。
したがって、閏秒テーブルは 2000年1月までは正確であることが保証される。
また、MzScheme は (確か version 102 の時点では)、 SECONDS->DATE と CURRENT-DATE 手続きを介して、 現在のタイムゾーン オフセットを取得する方法を提供している。
時刻と日付のオブジェクトを定義するために
MzScheme の DEFINE-STRUCT
を使用した。
これの代わりに「SRFI 9: レコード型の定義」
を使うこともできるだろう。
内部的に使用する手続きは TM:
で始まる名前にした。
ロケール関係の定数と手続きの名前には locale
が含まれている。
将来、ロケール関係の SRFI が定義されるなら、
代わりにそのコードを使うほうがよいだろう。
これらを基礎として、参照実装の残りの部分が実装されている。
テストコードも用意した。
前のバージョンの草案に対しては、 Mike Sperber, Marc Feely, Dave Mason, および "Prfnoff" も有用なコメントをくれた。 Shriram Krishnamurthi は編集上の助けをしてくれて感謝する。
DATE->STRING
手続きは
GNU C の date
関数と
scsh
の FORMAT-DATE
手続きをベースにした書式文字列を使用している。
Copyright (C) Neodesic Corporation (2000). All Rights Reserved.
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
(display (date->string (current-date 0)
"~4"))
: 2004-03-15T02:21:15Z