Tools.h++ 7.0 ユーザーズガイド: 3 - クラス RWDate の使用法

Copyright 1999 Rogue Wave Software
Copyright 1999 Sun Microsystems, Inc.

# クラス RWDate の使用法 | # 3 |

クラス RWDate は、ユリウス日として格納された日付を表現します。このクラスは、ソフトウェアで広く使用され、簡潔な表現によって迅速な暦計算を可能にし、うるう年などの細目を処理して、通常の暦形式との変換を簡単に実行できるようにします。

ユリウス日を Tools.h++ で使用して恩恵を得るために、その日を知る必要はありません。Tools.h++ が通常の暦の日付をユリウス日に変換するために使用するアルゴリズムは、Communications of the ACM, Volume 6, No.8, Aug. 1963 の 「Algorithm 199」の 444 ページに記載されています。

現在ほとんど全世界で使用されているグレゴリオ暦は、1582 年にグレゴリウス 13 世によって制定され、各国でさまざな時代に採用されました。英国では 1752 年 9 月 14 日に採用され、後に米国でも採用されるようになりました。グレゴリオ暦の採用以前の RWDate は、グレゴリオシステムから溯って推定したものであるという意味でしか有効ではないため、この点について説明しておきます。このような RWDate の出力、またはそのメソッドを使用した特定の日または月名の処理を行なうと、結果が予測できない場合があります。

## 例

重要なのは、RWDate を使用すると、通常使用している暦の日付を迅速かつ容易に操作できるということです。次に、このクラスの利点を示す例を示します。

ENIAC が初めて起動した 1945 年 2 月 14 日という日付を出力してから、大域ロケールを使用して、今日までの日数を計算し出力します。

    #include <rw/rwdate.h>
    #include <rw/rstream.h>

    int main(){
      // ENIAC の起動日
      RWDate d(14, "February", 1945);

      // 今日
      RWDate today;

      cout  << d.asString("%A, %B %d 19%y")
            << " was the day the ENIAC computer was" << endl
            << "first turned on.  "
            << today - d << " days have gone by since then. " << endl;

      return 0;
    }

#### プログラムからの出力

    Wednesday February 14, 1945 was the day the ENIAC computer was
    first turned on.  18636 days have gone by since then.

この計算では、経過日数が、プログラムをいつ実行するかによって決まることに注意してください。

## コンストラクタ

RWDate を生成する方法はいくつかあります。たとえば、

1. 現在の日付で RWDate を生成する1。

       RWDate d;

2. 通年での日 (1〜365) と年 (たとえば、1989 や 89)を指定して RWDate を生成します。クラスは 2 桁の年指定子をサポートしますが、できれば 4 桁を使用して、世紀が変わった場合の混乱を避けてください。

           RWDate d1(24, 2001);                   // 2001 年 1 月 24 日
           RWDate d2(24, 01);                     // 1901 年 1 月 24 日 (2 桁！)

3. 月における日 (1〜31) と月 (1〜12) と年を指定して `RWDate` を生成する。

           RWDate d(10, 3, 90);// 1990 年 3 月 10 日

4. `RWTime` から `RWDate` を生成する。

           RWTime t;                   // 現在の時刻
           RWDate d(t);

さらに、ロケール固有の文字列を使用して日付を生成することもできます。特に何も指定しなければ、デフォルトのロケールが使用されます。このロケールでは米国の規約と名前が使用されます。

        RWDate d1(10, "June", 90);             // 1990 年 6 月 10 日
        RWDate d2(10, "JUN", 90);              // 1990 年 6 月 10 日

ユーザーのシステムがフランス語ロケールをサポートしており、フランス語形式の月名を使用したい場合は、次のように記述することができます。

    dateloc.cpp
    #include <rw/rwdate.h>
    #include <rw/rstream.h>
    #include <rw/locale.h>
    #include <rw/cstring.h>
    main()
    {
      RWLocaleSnapshot us("C");
      RWLocaleSnapshot french("fr");       // 処理系依存         // 1

      RWCString americanDate("10 June 2025");
      RWCString frenchDate("10 Juin 2025");

      RWDate d(frenchDate, french);        // OK                 // 2

      cout << frenchDate << ((d.isValid()) ? " IS " : " IS NOT ")
           << "a valid date (french locale)." << endl << endl;

      RWDate bad = RWDate(frenchDate);                           // 3
      cout << frenchDate;
      cout << ((bad.isValid() && bad == d) ? " IS " : " IS NOT ")
           << "a valid date (default locale)." << endl << endl;

      bad = RWDate(americanDate, french);                        // 4
      cout << americanDate;
      cout << ((bad.isValid() && bad == d) ? " IS " : " IS NOT ")
           << "a valid date (french locale)." << endl << endl;

      cout << d << endl;                                         // 5
      cout << d.asString() << endl;                              // 6
      cout << d.asString('x', french) << endl;                   // 7

      return 0;
    }

以下、このコードを 1 行ずつ説明します。

1. ロケール "`fr`" のスナップショットを取ります。これは、ユーザーのシステムがこのロケールをサポートしていることを前提にしています。

2. 次のコンストラクタを使用して日付が作成されます。

           RWDate(unsigned day,    const char* month,  unsigned year,
                   const RWLocale& locale = RWLocale::global());

   第 2 引数の "`month`" は、特定のロケールの文脈の中でのみ意味を持ちます。この場合、行 1 で作成されたロケールを使用しています。結果は `06/10/1990` という (米国式の) 日付になります。

3. ここで、デフォルトロケールを使用して同じ日付を生成してみます。このロケールは C の書式設定規則だけを認識します。したがって、2002 年 6 月 10 日という日付は意味を持ちません。この場合は、既知の有効な日付と比較してください。

4. 同じ理由から、フランス語ロケールで、米国式の名前を使用して日付を作成しようとしても失敗します。ただし、万一の場合のために、既知の有効な日付と比較してください。

5. 行 2 で作成された日付が、デフォルトのロケール (つまり米国形式の規約) を使用して出力されます。結果は次のようになります。

   `06/10/90`

6. 日付が文字列に変換されてから出力されます。ここでもデフォルトのロケールが使用されます。結果は同じです。

   `06/10/90`

7. 日付が文字列に変換されますが、今度は行 1 で作成されたロケールが使用されます。結果は次のようになります。

   `10.06.90`

1 `RWDate` のデフォルトコンストラクタは今日の日付を記入するので、RWDate の大きな配列を生成すると処理速度が遅くなることがあります。この点が問題になる場合は、より速いコンストラクタを提供するクラスを `RWDate` から派生させ、そのクラスで配列を宣言してください。または、RWTValOrderedVector<RWDate>を使用してください。