日付と時刻ライブラリ

要約:
Curl® 言語では、複数のクラスを使用して日付と時刻を表示します。
  • DateTime クラスを使用して正確な時刻を表します。
  • DateTimeInfo クラスを使用して DateTime のさまざまな要素にアクセスします。
  • Time クラスを使用して時間量を表します。
Curl 言語では、複数のクラスを使用して日付と時刻を表示および操作します。次のクラスが含まれます。
これらのクラスにはすべて単一クラスである DateTime を介してアクセスできます。日付と時刻の操作の大半は DateTime クラスだけで処理できます。
また、Curl 言語は Time クラスを使用して時間量を表します。

時刻の表示

DateTime クラスを使用して正確な時刻を表すことができます。64 ビットの整数部分と 64 ビットの小数部分で構成される固定小数点値で、これらの時刻は エポック以降の秒として格納されています。エポックは 1970 年 1 月 1 日 午前零時 (UTC) です。
これは、Curl 言語では無限の範囲と精度で日付と時刻を効果的に表わすことができることを意味します。ただし、ホスト コンピュータの限界が原因で、これらの日付と時刻の解析または表示がこの範囲のサブセットに限定される場合があります。
UTC ベースのタイム ゾーンを使用する場合、日付と時間を表わすことができます。UTC カレンダーには夏時間がなく、グレゴリアンカレンダーから以前または以降を算出されています。
ローカル タイム ゾーンでは、表示できる日付の範囲がさらに制限されます。たとえば、既定のローカル タイム ゾーンは日付を 1970-01-01 00:00:00.000000 +0000 から 2038-01-19 03:14:07.000000 +0000 までの範囲で、ナノ秒近くの精度で表わします。
タイム ゾーンの範囲外の日付を指定するとエラーが返されます。
DateTime クラスの概要は次のとおりです。
DateTime はロケールを使用して、タイム ゾーンを決定したり、夏時間などの特別な日付と時刻に関する問題を処理します。

DateTime オブジェクトの作成

新しい DateTime を特定の時刻に初期化するには多くの方法があります。

例: DateTime オブジェクト
It is currently {DateTime}.

The first day of the 21st century is
{DateTime "01/01/2001"}.

The last day of the 20th century is
{DateTime year=2000, month=12, day=31}.

Golf was last played on the Moon
{DateTime "2/6/71 7:12:22 -0500"}.

DateTime の文字列への変換

DateTime はいくつかの異なる文字列の形式に変換できます。DateTime クラスには、人間が読み取り可能な形式で日付と時刻を返す object-describe メソッドがあります。さらに、DateTime.info のアクセッサを介して DateTimeInfo クラスのメソッドやアクセッサを利用し、異なる方法で日付と時刻の形式を次のように変更できます。次に例を示します。
使用可能な文字列形式の完全なリストは、DateTimeInfo を参照してください。
次にいくつかの例を示します。

例: DateTime を文字列に変換
{let moon-golf:DateTime =
    {DateTime "2/6/71 7:12:22 -0500"}
}
Golf was last played on the moon on {value moon-golf.info.locale-date} at
{value moon-golf.info.locale-time}.
To be specific it was {value moon-golf}.

日付と時刻の要素

  • DateTimeInfo クラスにより DateTime のさまざまな要素にアクセスできます。
  • 文字列形式と同様に、要素には DateTime.info アクセッサを介してアクセスします。たとえば、
    DateTimeInfo クラスの詳細は、DateTimeInfo セクションを参照してください。
    これらのアクセッサを使用してカスタム形式を作成できます。

    例: アクセッサを使用したカスタム形式の作成
    {let now:DateTime = {DateTime}}
    
    Today is {value now.info.locale-full}
    (that is,
     {value now.info.locale-weekday}
     the {ordinal now.info.day} day
     of the {ordinal now.info.month} month
     ({value now.info.locale-month})
     of the year {value now.info.year}
     at {value now.info.locale-time} {value now.info.timezone-name}).
    
    It is the {ordinal now.info.day-of-year} day of the year, which
    is the {ordinal now.info.day-of-week} day of the week, called
    {value now.info.locale-weekday}.
    

    DateTime 文字列の解析

    DateTime クラスにより、現在の時刻を String インスタンスから初期化できます。Curl の解析コードは、精度の高い ISO 8601 の特定の拡張フォームだけでなく、使いやすさを意図したいくつかの追加フォームも受け取ります。
    注意: 実際の日付を入力する必要があります。たとえば 2 月 29 日 を参照すると、閏年でない限りエラーになります。
    一般的に日付のフォームは次のとおりです。

    [date] [time] [utc-offset]
    date および time の両方が省略された場合、現在の日付と時刻と見なされます。date が省略され time が存在する場合、現在の日付と見なされます。date が存在して time が省略された場合、午前零時と見なされます。utc-offset が省略された場合、ローカル タイム ゾーンと見なされます。
    空の文字列は、ローカル タイム ゾーンの現在の日付と時刻を意味します。
    日付の指定では次の方法がサポートされています。

    yyyy-mm-dd
    mm/dd/yyyy
    mm/dd/yy
    mm-dd
    mm/dd
    2 桁の年は米国式で日付を入力するときだけ許可され、年数が 50 未満の場合は 21 世紀の年として処理され、それ以外の場合は 20 世紀の年として処理されます。
    年数に先行するゼロは省略できません。月と日に先行するゼロはオプションです。
    時刻の指定では次の方法がサポートされています。

    hh:mm
    hh:mm[am\|pm]
    hh:mm:ss
    hh:mm:ss.sssssss
    hh:mm:ss,sssssss
    米国式の am/pm 表記法を使用しない限り、時刻は 24 時間形式と見なされます。秒を指定しない場合は 0 と見なされます。小数部分を指定しない場合は 0 と見なされます。
    24 時間形式では、時刻の残りの要素がすべてがゼロの場合に 24 時と見なされ、次の日の午前零時と同義になります。
    12 時間形式では、時刻の範囲を 1 から 12 の間にする必要があります。12 時間表記法が無効になるのは、ISO 表記法を使用して日付が指定されている場合、ISO の区切り文字 "T" が時刻の前にある場合、時刻に明示的な秒フィールドがある場合、または明示的なタイム ゾーンが時刻に続く場合です。
    UTC オフセットの指定では次の方法がサポートされています。

    Z
    +hh
    -hh
    +hhmm
    -hhmm
    +hh:mm
    -hh:mm
    記号は、時刻フィールドを明瞭に指定するためのもので必ず指定します。UTC オフセットが省略された場合、ローカル タイム ゾーンが使用されます。値 Z+00 と同義です。UTC オフセットに先行する空白文字はオプションです。先行するゼロは必ず指定します。オフセットが 18 時間を超えることはありません。
    ローカル タイム ゾーンに夏時間 (DST) が含まれることがありますが、UTC オフセット時刻には含まれません。DST のために繰り返されて入力される時刻の場合、2 つのインスタンスのいずれかを指定することはできず、同じプラットホーム上でも入力されるたびに結果が異なる可能性があります。DST のために抜かされた時刻を入力する場合、DST の調整によって時刻が前方または後方に移動し、この方向は同じプラットホーム上でも入力ごとに異なる可能性があります。
    時間を指定するときに、ISO 8601 で指定のリテラル T を前に付けることができます。この場合、T と時刻の間に空白を挿入できません。日付の指定も、T と日付の間に空白を挿入できません。

    DateTime の正規化

    DateTime および DateTimeInfo を直接作成する場合に、実際の日付と時刻に対応しない暦表示が指定される場合があります。
    このような表示を DateTime に渡すと、すべての値が定義された範囲内に収まるように暦の四則演算法則によって調整されます。このプロセスは正規化と呼ばれ、一般的な暦操作の多くを簡単な方法で実行できるようにします。
    正常な日付を超えた日付の例とその正規化を次に示します。

    1999-01-321999-02-01
    1999-02-301999-03-02
    2000-02-301999-03-01
    2000-01-23742006-07-01 になります。
    上記のそれぞれにおいて、ひと月ごとに日数を削除して現在の月 (および年)を増加させ、すべての値が範囲内に収まるまで値が調整されます。これは、指定された日数を月に変換して日付を見つけるとも解釈できます。
    月、時間、分または秒が正常値を超えた場合も同様の規則が使用されます。

    1999-13-122000-01-12
    1999-200-32015-08-03
    04:06:10004:07:40
    1999-01-01 23:00:999999992002-03-04 08:46:39 になります。
    正常な範囲より小さい数値の日付や時刻を後方に正規化することもできます。

    1999-03-001999-02-28
    2000-03-002000-02-29
    2000-03-(-02)2000-02-27
    1999-(-10)-(-5)1998-01-26
    2000-01-01 00:00:-011999-12-31 23:59:59になります。
    新しい DateTime を作成する場合にキーワード引数を指定することによって、範囲外の値を使用して暦時刻を変更することができます。これはたいてい、端数を切捨てた時刻を簡単に作成することを目的としていますが、他にも範囲外の値を有効に利用するいくつかの方法があります。

    {DateTime day=0}
    前の暦月の最終日の午前零時を生成します。

    {DateTime hour=24}
    次の暦日の午前零時を生成します。
    既知の日付に基づいて日付を計算する場合も、範囲外の値を使用すると便利です。

    let now:DateTime = {DateTime}
    set now.info = {now.info.modify-clone new-day=(now.info.day+7)}
    現在から 7 日後の同じ時間を返します。現在から 7 日後の午前零時を得る場合にも似たようなテクニックを使用しますが、DateTime.default の端数の切り捨て処理を利用します。

    let now:DateTime = {DateTime}
    let future:DateTime = {DateTime now, day=(now.info.day+7)}

    時間の長さ

    Curl 言語では、時間の長さを Time によって表します。これは単に 15seconds または 13.32days などの時間量です。他の数量のように、異なる Time の単位を加算したり、自動的に変換処理することができます。

    例: Time クラスの使用
    {let some-seconds:Time = 23479233seconds}
    {let some-minutes:Time = 232643minutes}
    {let some-hours:Time = 83.343hours}
    {let total-time:Time = some-seconds + some-minutes + some-hours}
    The total time is {value total-time / 1day} days.
    
    次に説明するように、Time をいくつかの DateTime メソッドと関連して使用して、DateTime を結果的に変更することができます。

    DateTime の四則演算

    標準の加算および減算を使用して TimeDateTime に足したり引いたりすることができます。

    例: DateTime オブジェクトで加算を実行
    {let now:DateTime = {DateTime}}
    {let leave-in:Time = .5hour}
    
    If you want to leave in {value leave-in / 1s}
    seconds, set your alarm for
    {value (now + leave-in).info.locale-time}.
    
    DateTime の一部を加算および減算して、新しい DateTime を得ることもできます。この場合、実際の暦日にない日付と時刻の結果は DateTime クラスが自動的に修正します。

    例: DateTime クラスの部分的な加算と減算
    {let now:DateTime = {DateTime}}
    
    || Add 80 to day parameter in order to get a new date.
    {let returnday:DateTime = {DateTime now, day={value now.info.day + 80}}}
    
    If you left on an eighty-day around the world trip today,
    you'd get back on {value returnday.info.locale-date}
    
    || Since day=1 is the first of the month, day=0 must be the
    || previous day, that is, the last day of the previous month.
    Midnight of the last day of the previous month was
    {value {DateTime day=0}.info.locale-full}
    

    経過時間

    DateTime クラスは与えられた DateTime から経過した時間の合計を決定するために DateTime.elapsed メソッドを提供します。DateTime.elapsed は基礎となるDateTimeDataDateTimeData.elapsed を呼び出すための略記法です。

    例: DateTime クラスを使用した経過時間の表示
    || Use the "date normalization" feature of the DateTime class
    || to get midnight of the next day.
    {let midnight:DateTime = {DateTime hour=24}}
    
    It will be tomorrow in
    {value -{midnight.elapsed} / 1hour} hours.
    

    日付と時刻の比較

    DateTime.compare メソッドを使うと DateTime 同士を比較することができます。DateTime.compareDateTimeData.compare を使って基礎となるデータを比較します。

    例: 日付と時刻の比較
    || Acquire "now" once, for efficiency
    {let now:DateTime = {DateTime}}
    
    || Use optional parameters to set the time of meals.
    {let breakfast:DateTime = {DateTime now, hour=7}}
    {let lunch:DateTime = {DateTime now, hour=12}}
    {let dinner:DateTime = {DateTime now, hour=20}}
    
    {if {breakfast.compare now} < 0 then
        {text You missed breakfast.}
     else
        {text
            Breakfast is in
            {value -{breakfast.elapsed ending=now} / 1hour} hours.}
    }
    {if {lunch.compare now} < 0 then
        {text You missed lunch.}
     else
        {text
            Lunch is in
            {value -{lunch.elapsed ending=now} / 1hour} hours.}
    }
    {if {dinner.compare now} < 0 then
        {text You missed dinner.}
     else
        {text
            Dinner is in
            {value -{dinner.elapsed ending=now} / 1hour} hours.}
    }