noocyte のプログラミング研究室 〜プログラムは楽しげに走らねばならない♪〜

グレゴリオ暦・ユリウス暦・通算日数計算用
C言語ライブラリ Calendrier リファレンス (Ver.1.0)

公開:2008/10/15(水)
最終更新:2008/12/20(土)

グレゴリオ暦・ユリウス暦・通算日数計算用C言語ライブラリ Calendrier (Ver.1.0) のリファレンスです.
仕様は予告なく変更されることがあります.


0.目次

  1. 関数・マクロ一覧
    1. グレゴリオ暦/ユリウス暦基本関数
    2. グレゴリオ暦/ユリウス暦 ⇔ 通算日数/通算秒数変換
    3. 各種曜日計算
    4. その他の関数
  2. 変数一覧
    1. 曜日名文字列の配列
    2. 各月の日数/通算日数の配列
  3. データ型一覧
  4. 関数・マクロリファレンス
  5. 変数リファレンス
  6. データ型リファレンス
  7. 更新履歴

1.関数・マクロ一覧

1.1 グレゴリオ暦/ユリウス暦基本関数

関数・マクロ名 機能 浮動小数
使用
CalIsLeapYear() 指定された年が閏年か否かを判定する. ×
CalIsValidDate()
CalIsValidYMD()
日付が有効か否かを判定する. ×
CalDaysInMonth() 指定された月の日数を返す. ×
CalNextDate() 翌日の日付を求める. ×
CalPreviousDate() 前日の日付を求める. ×
CalCompareDates() 2つの日付を比較し,大小関係を判定する. ×
CalCompareTimes() 2つの時刻を比較し,大小関係を判定する. ×
CalCompareDateTimes() 2つの日時を比較し,大小関係を判定する. ×

1.2 グレゴリオ暦/ユリウス暦 ⇔ 通算日数/通算秒数変換

関数・マクロ名 機能 浮動小数
使用
CalDateToDays() 日付を整数型通算日数 (MJD,CJD,LD,RD など) に変換する. ×
CalDaysToDate() 整数型通算日数 (MJD,CJD,LD,RD など) を日付に変換する. ×
CalDateTimeToFDays() 日時を浮動小数型通算日数 (JD,MJD,CJD,LD,RD など) に変換する.
CalFDaysToDateTime() 浮動小数型通算日数 (JD,MJD,CJD,LD,RD など) を日時に変換する.
CalDateTimeToSeconds() 日時を通算秒数 (UNIX Time など) に変換する. ×
CalSecondsToDateTime() 通算秒数 (UNIX Time など) を日時に変換する. ×
CalDayOfYear() 日付を年内通算日数に変換する. ×
CalDayOfYearToDate() 年内通算日数を日付に変換する. ×
CalTimeToSeconds() 時刻を日内通算秒数に変換する. ×
CalSecondsToTime() 日内通算秒数を時刻に変換する. ×

1.3 各種曜日計算

関数・マクロ名 機能 浮動小数
使用
CalDayOfWeek() 通算日数 (グレゴリオ暦0年3月1日基準) から曜日番号を求める. ×
CalDayToWeekNumber() ○月d日 (w曜日) が,その月の何回目のw曜日かを返す. ×
CalNthDayOfWeekToDay() ある月のn回目のw曜日の日付を求める. ×
CalAnotherDayOfWeek() 同じ月の別の日の曜日を求める. ×

1.4 その他の関数

関数・マクロ名 機能 浮動小数
使用
CalDayFloor() 通算日数 (CalDays_t) の除算で端数切り下げ (商を−∞方向に丸める). ×
CalSecondFloor() 通算秒数 (CalSeconds_t) の除算で端数切り下げ (商を−∞方向に丸める). ×

2.変数一覧

2.1 曜日名文字列の配列

変数名 説明
CalDayNameOfWeekJaA 日本語の曜日名文字列 ("日","月",…) の配列.
CalDayNameOfWeekJaW 日本語の曜日名ワイド文字列 (L"日",L"月",…) の配列.
CalDayNameOfWeekEnA 英語の曜日名文字列 ("Sunday","Monday",…) の配列.
CalDayNameOfWeekEnW 英語の曜日名ワイド文字列 (L"Sunday",L"Monday",…) の配列.
CalDayAbbrevOfWeekEnA 英語の曜日略称文字列 ("Sun","Mon",…) の配列.
CalDayAbbrevOfWeekEnW 英語の曜日略称ワイド文字列 (L"Sun",L"Mon",…) の配列.

2.2 各月の日数/通算日数の配列

変数名 説明
calDaysInMonth 1〜12月の日数 (平年) の配列.
calDaysSinceJanuary1st 1月1日を第0日とする,1〜12月1日の通算日数 (平年) の配列.
calDaysSinceMarch1st 3月1日を第-1日とする,3〜14月1日の通算日数の配列.
(1〜2月は前年の13〜14月として扱う.)

3.データ型一覧

型名 説明
Calendar_t 暦の種別 (無符号整数型)
CalYear_t 年 (符号付整数型)
CalDays_t 整数型 (通算) 日数 (符号付整数型)
CalFDays_t 浮動小数型 (通算) 日数 (浮動小数型)
CalSeconds_t 通算秒数または秒数 (符号付整数型)
CalSecondOfDay_t 日内通算秒数および1日の秒数 (無符号整数型)
CalDate_t 日付 (構造体)
CalTime_t 時刻 (構造体)
CalConverter_t 日時 ⇔ 通算日時変換用構造体
CalDayDiv_t 整数除算の商と剰余 (通算日数用,構造体)
CalSecondDiv_t 整数除算の商と剰余 (通算秒数用,構造体)
CalDayOfWeek_t 曜日番号 (無符号整数型,0 〜 6)
CalError_t エラー番号 (無符号整数型)

4.関数・マクロリファレンス

CalAnotherDayOfWeek()
書式  :#include "Calendrier.h"
        CalDayOfWeek_t CalAnotherDayOfWeek(unsigned day, unsigned day0,
                                             CalDayOfWeek_t dow0);

機能  :同じ月の別の日の曜日を求める.

入力  :(1) day,day0:同じ月の日付.
        (2) dow0:day0 の曜日番号.

戻り値:ある月の day0 日が dow0 曜日であるとき,day 日の曜日番号を返す.
CalCompareDates()
書式  :#include "Calendrier.h"
        int CalCompareDates(const CalDate_t *date1, const CalDate_t *date2);

機能  :2つの日付の大小を比較する.

入力  :*date1,*date2:日付.同じ暦 (グレゴリオ暦同士またはユリウス暦同士)
        の日付でなければならない.

戻り値:*date1 < *date2 ならば−1.
        *date1 = *date2 ならば0.
        *date1 > *date2 ならば+1.
CalCompareDateTimes()
書式  :#include "Calendrier.h"
        int CalCompareDateTimes(const CalDate_t *date1,
                                  const CalTime_t *time1,
                                  const CalDate_t *date2,
                                  const CalTime_t *time2);

機能  :2つの日時の大小を比較する.

入力  :(*date1,*time1),(*date2,*time2):日時.*date1 と *date2 は同じ暦
        (グレゴリオ暦同士またはユリウス暦同士) の日付でなければならない.

戻り値:(*date1,*time1) < (*date2,*time2) ならば−1.
        (*date1,*time2) = (*date2,*time2) ならば0.
        (*date1,*time2) > (*date2,*time2) ならば+1.
CalCompareTimes()
書式  :#include "Calendrier.h"
        int CalCompareTimes(const CalTime_t *time1, const CalTime_t *time2);

機能  :2つの時刻の大小を比較する.

入力  :*time1,*time2:時刻.

戻り値:*time1 < *time2 ならば−1.
        *time1 = *time2 ならば0.
        *time1 > *time2 ならば+1.
CalDateTimeToFDays()
書式  :#include "Calendrier.h"
        CalError_t CalDateTimeToFDays(CalConverter_t *conv);

機能  :グレゴリオ暦またはユリウス暦の日時を浮動小数型通算日数に変換する.

注意  :(1) この関数は閏秒を考慮しない.浮動小数型通算日数は1日の長さが一定
            (86400秒) であることを前提としているので,閏秒を扱えない.

        (2) この関数は,現在のバージョンでは時差を考慮していない.つまり日時
            が UTC (注1) ならば通算日数の基準日時も UTC,日時が地方時ならば
            基準日時も地方時となる.必要ならばアプリケーション側で補正すること.
            ─────────────────────────────────
            注1) 閏秒を考慮しないので正確には UTC ではなく UT1 というべきかも.

入力  :*conv の下記メンバ.

        (1) calendar:暦の種別.次のうちのいずれか.
            ・CAL_GREGORIAN:グレゴリオ暦
            ・CAL_JULIAN   :ユリウス暦

        (2) epochDayF:浮動小数型通算日数の基準日時を指定する.epochDayF
            自体は,(calendar の値にかかわらず) グレゴリオ暦 0/03/01(水)
            00:00:00 を第0日とする浮動小数型通算日数.例えば次の値を指定
            できる.
            ・0.0:グレゴリオ暦 0/03/01(水) 00:00:00 を第0日とする通算日数
              を求める場合.
            ・EPOCH_JD,EPOCH_MJD:それぞれユリウス日および修正ユリウス日を
              求める場合.(これらの場合,日時は UTC で指定する.)
            ・EPOCH_EXCELTIME:Microsoft Excel のシリアル値に変換する場合.
              ただし Excel の「仕様」では本来平年である1900年が閏年として扱
              われるので,date が 1900/02/28(水) 以前の場合には1日ずれる.
              (また,Excel は 1900/01/01(月) 00:00:00 より過去の日時を表す
               シリアル値を正しく表示できない.)

        (3) (date,time,subsecond):calendar で指定された暦の日付および時刻.
            subsecond は1秒未満の部分 (0≦subsecond<1).

        (4) flags:0または次のフラグ.
            ・CALCONV_NODAYOFWEEK:曜日を計算しない.乗除算が遅い処理系で,
              曜日が不要な場合にこのフラグを指定すると少しは速くなるかも.

出力  :*conv の下記メンバ.
        (1) dayNumberF:(date, time,subsecond) に対応する浮動小数型通算
            日数 (epochDayF 基準).

        (2) dayNumber:date に対応する整数型通算日数 (epochDay 基準).

        (3) epochDay:dayNumber の基準日 (グレゴリオ暦 0/03/01(水) を第0日
            とする).現在のバージョンでは0になる.

        (4) secondOfday:time の日内通算秒数.(date 当日の 00:00:00 を第0秒
            とする.subsecond は上記範囲外であっても無視する.)

        (5) dayOfWeek:flags に CALCONV_NODAYOFWEEK フラグが指定されていなけ
            れば,date の曜日番号 (CAL_SUNDAY 〜 CAL_SATURDAY) が返される.

戻り値:エラーコード.
        (1) CAL_OK:変換成功.
        (2) CAL_E_INVALID_CALENDAR:calendar の値が不正.
        (3) CAL_E_INVALID_DATE:日付が不正.
            (現在のバージョンではチェックしていない.)
        (4) CAL_E_INVALID_TIME:時刻が不正.
            (現在のバージョンではチェックしていない.)
        (5) CAL_E_OVERFLOW:オーバーフローまたはアンダーフロー.
            (現在のバージョンではチェックしていない.)

使用例:グレゴリオ暦の日時 (UTC) をユリウス日 (JD) に変換する.

          CalConverter_t conv;
          CalError_t errorCode;

          // グレゴリオ暦の日付と時刻 (UTC) を設定する.
          conv.calendar = CAL_GREGORIAN; // グレゴリオ暦
          conv.date.year   = 年;
          conv.date.month  = 月;
          conv.date.day    = 日;
          conv.time.hour   = 時;
          conv.time.minute = 分;
          conv.time.second = 秒の整数部;
          conv.subsecond   = 秒の小数部;

          // 日時をユリウス日に変換する.
          conv.epochDayF = EPOCH_JD;     // ユリウス日の基準日時
          conv.flags = 0;
          if((errorCode = CalDateTimeToFDays(&conv)) != CAL_OK) goto Error;

          // 結果を表示する.(書式文字列は CalYear_t = long の場合)
          printf("グレゴリオ暦:%ld/%02u/%02u %02u:%02u:%02u+%.16G\n"
                 "ユリウス日:%.16G\n",
                 conv.date.year, conv.date.month, conv.date.day,
                 conv.time.hour, conv.time.minute, conv.time.second,
                 conv.subsecond, conv.dayNumberF);
CalDateTimeToSeconds()
書式  :#include "Calendrier.h"
        CalError_t CalDateTimeToSeconds(CalConverter_t *conv);

機能  :グレゴリオ暦またはユリウス暦の日付と時刻を通算秒数に変換する.

注意  :現在のバージョンでは,この関数は時差も閏秒も考慮しない.つまり日時が
        UTC (注1) ならば通算秒数の基準秒も UTC,日時が地方時ならば基準秒も
        地方時となる.必要ならばアプリケーション側で補正すること.
        ──────────────────────────────────
        注1) 閏秒を考慮しないので正確には UTC ではなく UT1 というべきかも.

入力  :*conv の下記メンバ.

        (1) calendar:暦の種別.次のうちのいずれか.
            ・CAL_GREGORIAN:グレゴリオ暦
            ・CAL_JULIAN   :ユリウス暦

        (2) epochSecond:通算秒数の基準秒 (第0秒) を指定する.epochSecond
            自体は,(calendar の値にかかわらず) グレゴリオ暦 1970/01/01(木)
            00:00:00 を第0秒とする通算秒数.例えば次の値を指定できる.
            ・EPOCHSECOND_UNIXTIME (EPOCH_UNIXTIME ではない):
              UNIX Time を 求める場合.(この場合,日時は UTC で指定する.)

        (3) (date,time):calendar で指定された暦の日付および時刻.

        (4) flags:0または次のフラグ.
            ・CALCONV_NODAYOFWEEK:曜日を計算しない.乗除算が遅い処理系で,
              曜日が不要な場合にこのフラグを指定すると少しは速くなるかも.

出力  :*conv の下記メンバ.

        (1) secondNumber:(date, time) に対応する通算秒数 (epochSecond 基準).

        (2) dayNumber:date に対応する通算日数 (epochDay 基準).

        (3) epochDay:dayNumber の基準日を,グレゴリオ暦 0/03/01(水) を第0日
            とする通算日数で指定する.現在のバージョンでは DAYNUMBER_19700101,
            つまり 1970/01/01(木) になる.

        (4) secondOfday:time の日内通算秒数.
            (date 当日の 00:00:00 を第0秒とする.)

        (5) dayOfWeek:flags に CALCONV_NODAYOFWEEK フラグが指定されていなけ
            れば,date の曜日番号 (CAL_SUNDAY 〜 CAL_SATURDAY) が返される.

戻り値:エラーコード.

        (1) CAL_OK:変換成功.
        (2) CAL_E_INVALID_CALENDAR:calendar の値が不正.
        (3) CAL_E_INVALID_DATE:日付が不正.
            (現在のバージョンではチェックしていない.)
        (4) CAL_E_INVALID_TIME:時刻が不正.
            (現在のバージョンではチェックしていない.)
        (5) CAL_E_OVERFLOW:オーバーフローまたはアンダーフロー.
            (現在のバージョンではチェックしていない.)

使用例:グレゴリオ暦の日時 (UTC) を UNIX Time に変換する.

          CalConverter_t conv;
          CalError_t errorCode;

          // グレゴリオ暦の日付と時刻 (UTC) を設定する.
          conv.calendar = CAL_GREGORIAN; // グレゴリオ暦
          conv.date.year   = 年;
          conv.date.month  = 月;
          conv.date.day    = 日;
          conv.time.hour   = 時;
          conv.time.minute = 分;
          conv.time.second = 秒;

          // 日時を UNIX Time に変換する.
          conv.epochSecond = EPOCHSECOND_UNIXTIME; // EPOCH_UNIXTIME ではない!
          conv.flags = 0;
          if((errorCode = CalDateTimeToSeconds(&conv)) != CAL_OK) goto Error;

          // 結果を表示する.
          // (書式文字列は CalYear_tCalSeconds_t = long の場合)
          printf("グレゴリオ暦:%ld/%02u/%02u %02u:%02u:%02u  UNIX Time:%ld\n",
                 conv.date.year, conv.date.month, conv.date.day,
                 conv.time.hour, conv.time.minute, conv.time.second,
                 conv.secondNumber);
CalDateToDays()
書式  :#include "Calendrier.h"
        CalError_t CalDateToDays(CalConverter_t *conv);

機能  :グレゴリオ暦またはユリウス暦の日付を (整数型) 通算日数に変換する.

注意  :通算日数には UTC を基準とするものと,地方時を基準とするものがあるが,
        この関数は時差を考慮しない.つまり日付が UTC ならば通算日数の基準日
        も UTC,日付が地方時ならば基準日も地方時となる.必要ならばアプリケー
        ション側で補正すること.

入力  :*conv の下記メンバ.

        (1) calendar:暦の種別.次のうちのいずれか.
            ・CAL_GREGORIAN:グレゴリオ暦
            ・CAL_JULIAN   :ユリウス暦

        (2) epochDay:通算日数の基準日 (第0日) を指定する.epochDay 自体は,
            (calendar の値にかかわらず) グレゴリオ暦 0/03/01(水) を第0日と
            する通算日数.例えば次の値を指定できる.

            ・0:グレゴリオ暦 0/03/01(水) を第0日とする通算日数を求める場合.
            ・EPOCH_CJD:Chronological Julian Day (CJD) を求める場合.
            ・EPOCH_MJD:修正ユリウス日 (Modified Julian Day,MJD).
            ・EPOCH_LD:リリウス日 (Lilian Day Number,LD).
            ・EPOCH_RD:Rata Die (RD).
            ・EPOCH_UNIXTIME:UNIX Time (ただし1秒単位ではなく1日単位).
            ・EPOCH_ANSIDATE:ANSI Date.

            注意:EPOCH_JD (ユリウス日の基準日) は整数ではないので指定不可.
                  ユリウス日を求めたい場合は後述の使用例 (2) のようにするか,
                  CalDateTimeToFDays() を使用すること.

        (3) date:calendar で指定された暦の日付.

        (4) flags:0または次のフラグ.
            ・CALCONV_NODAYOFWEEK:曜日を計算しない.乗除算が遅い処理系で,
              曜日が不要な場合にこのフラグを指定すると少しは速くなるかも.

出力  :*conv の下記メンバ.

        (1) dayNumber:date に対応する通算日数 (epochDay を第0日とする).

        (2) dayOfWeek:flags に CALCONV_NODAYOFWEEK フラグが指定されていなけ
            れば,date の曜日番号 (CAL_SUNDAY 〜 CAL_SATURDAY) が返される.

戻り値:エラーコード.
        (1) CAL_OK:変換成功.
        (2) CAL_E_INVALID_CALENDAR:calendar の値が不正.
        (3) CAL_E_INVALID_DATE:日付が不正.
            (現在のバージョンではチェックしていない.)
        (4) CAL_E_OVERFLOW:オーバーフローまたはアンダーフロー.
            (現在のバージョンではチェックしていない.)

使用例:(1) グレゴリオ暦の日付を修正ユリウス日 (MJD) に変換する.

              CalConverter_t conv;
              CalError_t errorCode;

              // グレゴリオ暦の日付を (MJD だから UTC で) 指定.
              conv.calendar   = CAL_GREGORIAN;
              conv.date.year  = 2008;
              conv.date.month = 12;
              conv.date.day   = 31;

              // conv.date を MJD に変換する.
              conv.epochDay = EPOCH_MJD; // MJD の基準日
              conv.flags = 0;
              if((errorCode = CalDateToDays(&conv)) != CAL_OK) goto Error;

              // 結果を表示する.
              // (書式文字列は CalYear_tCalDays_t = long の場合)
              printf("グレゴリオ暦:%ld/%02u/%02u MJD:%ld\n",
                     conv.date.year, conv.date.month, conv.date.day,
                     conv.dayNumber);

        (2) 同じ日付に対して複数種類の通算日数を計算する場合には,次のように
            まず conv.epochDay=0 とした通算日数を計算し,それから各通算日数
            の基準日 (EPOCH_*) との差を求める方が効率的.

              #define CAL_USE_FLOAT    // CalFDays_t を使用する場合に必要.
              #include "Calendrier.h"

              CalConverter_t conv;
              CalDays_t mjd, cjd;
              CalFDays_t jd;           // ユリウス日は浮動小数型
              CalError_t errorCode;

              // グレゴリオ暦 2008/12/31(水) を指定.
              conv.calendar = CAL_GREGORIAN;
              conv.date.year  = 2008;
              conv.date.month = 12;
              conv.date.day   = 31;

              // 日付を通算日数 (グレゴリオ暦 0/03/01(水) 基準) に変換する.
              conv.epochDay = 0; // グレゴリオ暦 0/03/01(水) 基準
              conv.flags = 0;
              if((errorCode = CalDateToDays(&conv)) != CAL_OK) goto Error;

              // conv.dayNumber (グレゴリオ暦 0/03/01(水) 基準) を
              // 各種通算日数に変換する.
              mjd = conv.dayNumber - EPOCH_MJD; // 修正ユリウス日
              cjd = conv.dayNumber - EPOCH_CJD; // Chronological Julian Day
              jd = (CalFDays_t)conv.dayNumber - EPOCH_JD; // ユリウス日
CalDayFloor()
書式  :#include "Calendrier.h"
        void CalDayFloor(CalDayDiv_t *qr,
                          CalDays_t dividend, CalDays_t divisor);

機能  :整数除算で端数切り下げ (商を−∞方向に丸める).

入力  :(1) dividend:被除数 (任意の整数).
        (2) divisor:除数 (>0).

出力  :*qr:商および剰余.
        (1) 商 (qr->quot):有理数 dividend/divisor の小数部を−∞方向に
            丸めた整数値.つまり有理数 dividend/divisor 以下で最大の整数.
        (2) 剰余 (qr->rem)
            ・rem == dividend - quot * divisor
            ・0 ≦ rem < divisor

参考  :端数処理 (Wikipedia)

関連  :CalSecondFloor().
CalDayOfWeek()
書式  :#include "Calendrier.h"
        CalDayOfWeek_t CalDayOfWeek(CalDays_t dayNumber)

機能  :通算日数から曜日番号を求める.

入力  :dayNumber:通算日数 (第0日=グレゴリオ暦 0/03/01(水)).

戻り値:dayNumber に対応する曜日番号 (CAL_SUNDAY 〜 CAL_SATURDAY).
CalDayOfYear()
書式  :#include "Calendrier.h"
        unsigned CalDayOfYear(CalYear_t year, unsigned month, unsigned day,
                               Calendar_t calendar);

機能  :日付から年内通算日数を求める.

入力  :(1) (year, month, day):日付.
        (2) calendar:暦の種別.次のうちのいずれか.
            ・CAL_GREGORIAN:グレゴリオ暦
            ・CAL_JULIAN   :ユリウス暦

戻り値:year年1月1日を第0日とする年内通算日数.
CalDayOfYearToDate()
書式  :#include "Calendrier.h"
        CalError_t CalDayOfYearToDate(CalDate_t *date, unsigned dayOfYear,
                                        Calendar_t calendar);

機能  :年内通算日数から日付を求める.

入力  :(1) date->year:年.
        (2) dayOfYear:year年1月1日を第0日とする年内通算日数.
        (3) calendar:暦の種別.次のうちのいずれか.
            ・CAL_GREGORIAN:グレゴリオ暦
            ・CAL_JULIAN   :ユリウス暦

出力  :(1) date->month:月.
        (2) date->day:日.

戻り値:エラーコード.
        (1) CAL_OK:変換成功.
        (2) CAL_E_INVALID_CALENDAR:calendar の値が不正.
CalDaysInMonth()
書式  :#include "Calendrier.h"
        unsigned CalDaysInMonth(CalYear_t year, unsigned month, Calendar_t calendar);

機能  :指定された月の日数を求める.

入力  :(1) year:年.
        (2) month:月 (1〜12).
        (3) calendar:暦の種別.次のうちのいずれか.
            ・CAL_GREGORIAN:グレゴリオ暦
            ・CAL_JULIAN   :ユリウス暦

戻り値:calendar 暦 year 年 month 月の日数.
CalDaysToDate()
書式  :#include "Calendrier.h"
        CalError_t CalDaysToDate(CalConverter_t *conv);

機能  :(整数型) 通算日数をグレゴリオ暦またはユリウス暦の日付に変換する.

注意  :通算日数には UTC を基準とするものと,地方時を基準とするものがあるが,
        この関数は時差を考慮しない.つまり通算日数の基準日が UTC (注1) なら
        ば日付も UTC,基準日が地方時ならば日付も地方時となる.必要ならばアプ
        リケーション側で補正すること.
        ──────────────────────────────────
        注1) 閏秒を考慮しないので正確には UTC ではなく UT1 というべきかも.

入力  :*conv の下記メンバ.

        (1) calendar:暦の種別.次のうちのいずれか.
            ・CAL_GREGORIAN:グレゴリオ暦
            ・CAL_JULIAN   :ユリウス暦

        (2) epochDay:通算日数の基準日 (第0日) を指定する.
            詳細は CalDateToDays() の epochDay の説明を参照.

            注意:EPOCH_JD (ユリウス日の基準日) は整数ではないので指定不可.
                  ユリウス日を使いたい場合は後述の使用例 (2) のようにするか,
                  CalFDaysToDateTime() を使用すること.

        (3) dayNumber:通算日数 (epochDay 基準).

        (4) flags:0または次のフラグ.
            ・CALCONV_NODAYOFWEEK:曜日を計算しない.乗除算が遅い処理系で,
              曜日が不要な場合にこのフラグを指定すると少しは速くなるかも.

出力  :*conv の下記メンバ.

        (1) date:dayNumber に対応する,calendar で指定された暦の日付.

        (2) dayOfWeek:flags に CALCONV_NODAYOFWEEK フラグが指定されていなけ
            れば,date の曜日番号 (CAL_SUNDAY 〜 CAL_SATURDAY) が返される.

戻り値:エラーコード.
        (1) CAL_OK:変換成功.
        (2) CAL_E_INVALID_CALENDAR:calendar の値が不正.
        (3) CAL_E_OVERFLOW:オーバーフローまたはアンダーフロー.
            (現在のバージョンではチェックしていない.)

使用例:(1) 修正ユリウス日をグレゴリオ暦の日付に変換する.

              CalConverter_t conv;
              CalError_t errorCode;
              const CalDays_t mjd = 修正ユリウス日;

              // 修正ユリウス日 (MJD) を指定.
              conv.epochDay = EPOCH_MJD;
              conv.dayNumber = mjd;

              // conv.dayNumber をグレゴリオ暦の日付に変換する.
              conv.calendar = CAL_GREGORIAN; // グレゴリオ暦を指定.
              conv.flags = 0;
              if((errorCode = CalDaysToDate(&conv)) != CAL_OK) goto Error;

              // 結果を表示する.
              // (書式文字列は CalYear_tCalDays_t = long の場合)
              printf("グレゴリオ暦:%ld/%02u/%02u MJD:%ld\n",
                     conv.date.year, conv.date.month, conv.date.day,
                     conv.dayNumber);

        (2) ユリウス日をユリウス暦の日付に変換する.

              #define CAL_USE_FLOAT    // CalFDays_t を使用するために必要.
              #include <math.h>        // for floor()
              #include "Calendrier.h"

              CalConverter_t conv;
              CalError_t errorCode;
              const CalFDays_t jd = ユリウス日; // 整数型ではなく浮動小数型

              // ユリウス日 (浮動小数型) を,グレゴリオ暦
              // 0/03/01(水) 00:00:00 基準に変更する.
              // (00:00:00 付近の時刻を変換する場合には計算誤差に注意!)
              conv.epochDay = 0; // グレゴリオ暦 0/03/01(水) 基準
              conv.dayNumber = (CalDays_t)floor(jd + EPOCH_JD);

              // conv.dayNumber をユリウス暦の日付に変更する.
              conv.calendar = CAL_JULIAN; // ユリウス暦を指定.
              conv.flags = 0;
              if((errorCode = CalDaysToDate(&conv)) != CAL_OK) goto Error;

              // 結果を表示する.(書式文字列は CalYear_t = long の場合)
              printf("ユリウス暦:%ld/%02u/%02u JD:%.16G\n",
                     conv.date.year, conv.date.month, conv.date.day, jd);
CalDayToWeekNumber()
書式  :#include "Calendrier.h"
        unsigned CalDayToWeekNumber(unsigned day);

機能  :○月day日 (w曜日) が,その月の何回目のw曜日か (週番号) を返す.

入力  :day:日 (1〜31).

戻り値:○月day日の週番号 (1〜5).
CalFDaysToDateTime()
書式  :#include "Calendrier.h"
        CalError_t CalFDaysToDateTime(CalConverter_t *conv);

機能  :浮動小数型通算日数をグレゴリオ暦またはユリウス暦の日時に変換する.

注意  :(1) この関数は閏秒を考慮しない.浮動小数型通算日数は1日の長さが一定
            (86400秒) であることを前提としているので,閏秒を扱えない.

        (2) この関数は,現在のバージョンでは時差を考慮していない.つまり通算
            日数が UTC (注1) 基準ならば日時も UTC,通算日数が地方時基準なら
            ば日時も地方時となる.必要ならばアプリケーション側で補正すること.
            ────────────────────────────────
            注1) 閏秒を考慮しないので正確には UTC ではなく UT1 というべきかも.

入力  :*conv の下記メンバ.

        (1) calendar:暦の種別.次のうちのいずれか.
            ・CAL_GREGORIAN:グレゴリオ暦
            ・CAL_JULIAN   :ユリウス暦

        (2) epochDayF:浮動小数型通算日数の基準日時を指定する.
            詳しくは CalDateTimeToFDays() の epochDayF の説明を参照.

        (3) dayNumberF:浮動小数型通算日数 (epochDayF 基準).

        (4) flags:0または次のフラグ.
            ・CALCONV_NODAYOFWEEK:曜日を計算しない.乗除算が遅い処理系で,
              曜日が不要な場合にこのフラグを指定すると少しは速くなるかも.

出力  :*conv の下記メンバ.

        (1) (date,time,subsecond):dayNumberF に対応する,
            calendar で指定された暦の日付および時刻.
            subsecond は1秒未満の部分 (0≦subsecond<1).

        (2) dayNumber:date に対応する整数型通算日数 (epochDay 基準).

        (3) epochDay:dayNumber の基準日 (グレゴリオ暦 0/03/01(水) を
            第0日とする).現在のバージョンでは0になる.

        (4) secondOfday:time の日内通算秒数.
            (date 当日の 00:00:00 を第0秒とする.1秒未満切り捨て.)

        (5) dayOfWeek:flags に CALCONV_NODAYOFWEEK フラグが指定されていなけ
            れば,date の曜日番号 (CAL_SUNDAY 〜 CAL_SATURDAY) が返される.

戻り値:エラーコード.
        (1) CAL_OK:変換成功.
        (2) CAL_E_INVALID_CALENDAR:calendar の値が不正.
        (3) CAL_E_OVERFLOW:オーバーフローまたはアンダーフロー.
            (現在のバージョンではチェックしていない.)

使用例:ユリウス日 (JD) をグレゴリオ暦の日時 (UTC) に変換する.

          CalConverter_t conv;
          CalError_t errorCode;

          // ユリウス日を指定.
          conv.epochDayF = EPOCH_JD;    // ユリウス日の基準日時
          conv.dayNumberF = ユリウス日;

          // ユリウス日をグレゴリオ暦の日時 (UTC) に変換する.
          conv.calendar = CAL_GREGORIAN; // グレゴリオ暦
          conv.flags = 0;
          if((errorCode = CalFDaysToDateTime(&conv)) != CAL_OK) goto Error;

          // 結果を表示する.(書式文字列は CalYear_t = long の場合)
          printf("グレゴリオ暦:%ld/%02u/%02u %02u:%02u:%02u+%.16G\n"
                 "ユリウス日:%.16G\n",
                 conv.date.year, conv.date.month, conv.date.day,
                 conv.time.hour, conv.time.minute, conv.time.second,
                 conv.subsecond, conv.dayNumberF);
CalIsLeapYear()
書式  :#include "Calendrier.h"
        Bool CalIsLeapYear(CalYear_t year, Calendar_t calendar);

機能  :指定された年が閏年か否かを判定する.

入力  :(1) year:年.
        (2) calendar:暦の種別.次のうちのいずれか.
            ・CAL_GREGORIAN:グレゴリオ暦
            ・CAL_JULIAN   :ユリウス暦

戻り値:year 年が閏年のときそのときに限り真.

参考  :除算回数を極力減らして高速化を図っている.
        ・ユリウス暦の場合:除算を全く使用しない.
        ・グレゴリオ暦の場合:4の倍数年のときに限り除算を1回だけ行う.
          したがって平均除算回数は 1/4 回.
CalIsValidDate()CalIsValidYMD()
書式  :#include "Calendrier.h"
        Bool CalIsValidYMD(CalYear_t year, unsigned month, unsigned day,
                             Calendar_t calendar);
        Bool CalIsValidDate(const CalDate_t *date, Calendar_t calendar); // マクロ

機能  :日付が有効か否かを判定する.

入力  :(1) (year, month, day) または *date:日付.
        (2) calendar:暦の種別.次のうちのいずれか.
            ・CAL_GREGORIAN:グレゴリオ暦
            ・CAL_JULIAN   :ユリウス暦

戻り値:日付が有効なときそのときに限り真.
CalNextDate()
書式  :#include "Calendrier.h"
        void CalNextDate(CalDate_t *date, Calendar_t calendar);

機能  :翌日の日付を取得する (日付をインクリメントする).

入出力:*date:グレゴリオ暦またはユリウス暦の日付.

入力  :calendar:暦の種別.次のうちのいずれか.
        ・CAL_GREGORIAN:グレゴリオ暦
        ・CAL_JULIAN   :ユリウス暦
CalNthDayOfWeekToDay()
書式  :#include "Calendrier.h"
        unsigned CalNthDayOfWeekToDay(unsigned n,
                                         CalDayOfWeek_t dow, CalDayOfWeek_t dow1);

機能  :ある月のn回目のdow曜日の日付を求める.

入力  :(1) n:1〜5.
        (2) dow:曜日番号 (CAL_SUNDAY 〜 CAL_SATURDAY).
        (3) dow1:その月の1日の曜日番号.

戻り値:その月のn回目の dow 曜日の日付.

例    :2008年11月:1日は土曜で,第3金曜は21日.
            CalNthDayOfWeekToDay(3, CAL_FRIDAY, CAL_SATURDAY) == 21.
CalPreviousDate()
書式  :#include "Calendrier.h"
        void CalPreviousDate(CalDate_t *date, Calendar_t calendar);

機能  :前日の日付を取得する (日付をデクリメントする).

入出力:*date:グレゴリオ暦またはユリウス暦の日付.

入力  :calendar:暦の種別.次のうちのいずれか.
        ・CAL_GREGORIAN:グレゴリオ暦
        ・CAL_JULIAN   :ユリウス暦
CalSecondFloor()
書式  :#include "Calendrier.h"
        void CalSecondFloor(CalSecondDiv_t *qr,
                              CalSeconds_t dividend, CalSeconds_t divisor);

機能  :整数除算で端数切り下げ (商を−∞方向に丸める).

入力  :(1) dividend:被除数 (任意の整数).
        (2) divisor:除数 (>0).

出力  :*qr:商および剰余.
        (1) 商 (qr->quot):有理数 dividend/divisor の小数部を−∞方向に
            丸めた整数値.つまり有理数 dividend/divisor 以下で最大の整数.
        (2) 剰余 (qr->rem)
            ・rem == dividend - quot * divisor
            ・0 ≦ rem < divisor

参考  :端数処理 (Wikipedia)

関連  :CalDayFloor().
CalSecondsToDateTime()
書式  :#include "Calendrier.h"
        CalError_t CalSecondsToDateTime(CalConverter_t *conv);

機能  :通算秒数をグレゴリオ暦またはユリウス暦の日付と時刻に変換する.

注意  :現在のバージョンでは,この関数は時差も閏秒も考慮しない.つまり日時
        が UTC (注1) ならば基準秒も UTC,日時が地方時ならば基準秒も地方時
        となる.必要ならばアプリケーション側で補正すること.
        ──────────────────────────────────
        注1) 閏秒を考慮しないので正確には UTC ではなく UT1 というべきかも.

入力  :*conv の下記メンバ.

        (1) calendar:暦の種別.次のうちのいずれか.
            ・CAL_GREGORIAN:グレゴリオ暦
            ・CAL_JULIAN   :ユリウス暦

        (2) epochSecond:通算秒数の基準秒 (第0秒) を指定する.
            詳しくは CalDateTimeToSeconds() の epochSecond の説明を参照.

        (3) secondNumber:通算秒数 (epochSecond 基準).

        (4) flags:0または次のフラグ.
            ・CALCONV_NODAYOFWEEK:曜日を計算しない.乗除算が遅い処理系で,
              曜日が不要な場合にこのフラグを指定すると少しは速くなるかも.

出力  :*conv の下記メンバ.

        (1) (date,time):secondNumber に対応する日付および時刻.

        (2) dayNumber:date に対応する通算日数 (epochDay 基準).

        (3) epochDay:dayNumber の基準日 (グレゴリオ暦 0/03/01(水) を
            第0日とする).現在のバージョンでは DAYNUMBER_19700101,
            つまり 1970/01/01(木).

        (4) secondOfday:time の日内通算秒数.
            (date 当日の 00:00:00 を第0秒とする.)

        (5) dayOfWeek:flags に CALCONV_NODAYOFWEEK フラグが指定されていなけ
            れば,date の曜日番号 (CAL_SUNDAY 〜 CAL_SATURDAY) が返される.

戻り値:エラーコード.
        (1) CAL_OK:変換成功.
        (2) CAL_E_INVALID_CALENDAR:calendar の値が不正.
        (3) CAL_E_OVERFLOW:年 (date.year) がオーバーフローまたは
            アンダーフローした.(現在のバージョンではチェックしていない.)

使用例:UNIX Time をグレゴリオ暦の日時 (UTC) に変換する.

          CalConverter_t conv;
          CalError_t errorCode;
          CalSeconds_t unixTime = <UNIX Time>;

          // UNIX Time 
          conv.epochSecond = EPOCHSECOND_UNIXTIME; // UNIX Time の基準秒
          conv.secondNumber = unixTime;

          // UNIX Time をグレゴリオ暦の日付と時刻 (UTC) に変換する.
          conv.calendar = CAL_GREGORIAN; // グレゴリオ暦
          conv.flags = 0;
          if((errorCode = CalSecondsToDateTime(&conv)) != CAL_OK) goto Error;

          // 結果を表示する.
          // (書式文字列は CalYear_tCalSeconds_t = long の場合)
          printf("グレゴリオ暦:%ld/%02u/%02u %02u:%02u:%02u  UNIX Time:%ld\n",
                 conv.date.year, conv.date.month, conv.date.day,
                 conv.time.hour, conv.time.minute, conv.time.second,
                 conv.secondNumber);
CalSecondsToTime()
書式  :#include "Calendrier.h"
        void CalSecondsToTime(CalTime_t *time, CalSecondOfDay_t secondOfDay);

機能  :日内通算秒数を時刻に変換する.閏秒には未対応.

入力  :secondOfDay:日内通算秒数 (0〜86399,00:00:00 を第0秒とする).

出力  :*time:secondOfDay に対応する時刻.
CalTimeToSeconds()
書式  :#include "Calendrier.h"
        CalSecondOfDay_t CalTimeToSeconds(const CalTime_t *time);

機能  :時刻を日内通算秒数に変換する.閏秒にも対応.

入力  :*time:時刻.

戻り値:*time の日内通算秒数 (00:00:00 を第0秒とする).

5.変数リファレンス

calDaysInMonth
書式  :#include "Calendrier.h"
        extern const unsigned char calDaysInMonth[CAL_NMONTHS];

説明  :1〜12月の日数 (平年) の配列.
calDaysSinceJanuary1st
書式  :#include "Calendrier.h"
        extern const unsigned short calDaysSinceJanuary1st[CAL_NMONTHS];

説明  :1月1日を第0日とする,各月1日の通算日数 (平年) の配列.
calDaysSinceMarch1st
書式  :#include "Calendrier.h"
        extern const short calDaysSinceMarch1st[CAL_NMONTHS];

説明  :3月1日を第(-1)日とする,3〜14月1日の通算日数 (平年) の配列.
        (1〜2月は前年の13〜14月として扱う.)
CalDayAbbrevOfWeekEnACalDayAbbrevOfWeekEnW
書式  :#include "Calendrier.h"
        extern const char CalDayAbbrevOfWeekEnA[CAL_NDAYSOFWEEK][4];
        #ifdef CAL_USE_WCHAR
        extern const wchar_t CalDayAbbrevOfWeekEnW[CAL_NDAYSOFWEEK][4];
        #endif /* CAL_USE_WCHAR */

説明  :曜日の英語略称文字列 (char/wchar_t) の配列.("Sun","Mon",…,"Sat")
CalDayNameOfWeekEnACalDayNameOfWeekEnW
書式  :#include "Calendrier.h"
        extern const char CalDayNameOfWeekEnA[CAL_NDAYSOFWEEK][10];
        #ifdef CAL_USE_WCHAR
        extern const wchar_t CalDayNameOfWeekEnW[CAL_NDAYSOFWEEK][10];
        #endif /* CAL_USE_WCHAR */

説明  :曜日の英語名文字列 (char/wchar_t) の配列.("Sunday","Monday",…,"Saturday")
CalDayNameOfWeekJaACalDayNameOfWeekJaW
書式  :#include "Calendrier.h"
        extern const char CalDayNameOfWeekJaA[CAL_NDAYSOFWEEK][4];
        #ifdef CAL_USE_WCHAR
        extern const wchar_t CalDayNameOfWeekJaW[CAL_NDAYSOFWEEK][2];
        #endif /* CAL_USE_WCHAR */

説明  :曜日の日本語名文字列 (char/wchar_t) の配列.("日","月",…,"土")

6.データ型リファレンス

CalConverter_t
日時 ⇔ 通算日数/通算秒数変換の入出力およびパラメータを受け渡すための構造体.
typedef struct {
  CalSeconds_t epochSecond;     // 基準秒
  CalSeconds_t secondNumber;    // 通算秒数 (epochSecond 基準)
  CalDays_t epochDay;           // 整数型基準日
  CalDays_t dayNumber;          // 整数型通算日数 (epoch 基準)
  CalDate_t date;               // 日付 (年,月,日)
  CalTime_t time;               // 時刻 (時,分,秒 (整数部))
  CalDayOfWeek_t dayOfWeek;     // 曜日番号 (CAL_SUNDAY 〜 CAL_SATURDAY)
  Calendar_t calendar;          // 暦の種別
  unsigned char flags;          // フラグ
#define CALCONV_NODAYOFWEEK   0x01 // 曜日を計算しない.

  CalSecondOfDay_t secondOfDay; // 日内通算秒数

#ifdef CAL_USE_FLOAT
  // 浮動小数を使用する場合
  CalFDays_t epochDayF;         // 浮動小数型基準日
  CalFDays_t dayNumberF;        // 浮動小数型通算日数 (シリアル値)
  double subsecond;             // 秒 (小数部)
#endif /* CAL_USE_FLOAT */
} CalConverter_t;
CalDate_t
日付を表す構造体.
typedef struct {
  CalYear_t year;       // 年
  unsigned char month;  // 月 (1〜12)
  unsigned char day;    // 日 (1〜31)
} CalDate_t;
CalDayDiv_t
通算日数の除算結果 (商および剰余) を受け渡すための構造体.
(C標準ライブラリの div_t,ldiv_t の CalDays_t 版.)
typedef struct {
  CalDays_t quot, rem;
} CalDayDiv_t;
CalDayOfWeek_t
曜日番号 (0〜6).
typedef unsigned char CalDayOfWeek_t;

#define CAL_SUNDAY      0
#define CAL_MONDAY      1
#define CAL_TUESDAY     2
#define CAL_WEDNESDAY   3
#define CAL_THURSDAY    4
#define CAL_FRIDAY      5
#define CAL_SATURDAY    6

#define CAL_NDAYSOFWEEK 7 // 曜日の総数
CalDays_t
通算日数または日数 (差) を表す符号付整数型. CalYear_t 型で表現できるすべての年を扱いたい場合, 有効ビット数が CalYear_t よりも9ビット以上多くなければならない. 通常,4バイト以上の符号付整数型を使用する.
typedef long CalDays_t;  // デフォルトの定義 (変更可能)
Calendar_t
暦 ID (暦の種別を表す無符号整数).
#define CAL_GREGORIAN  0 // グレゴリオ暦
#define CAL_JULIAN     1 // ユリウス暦

#define CAL_NCALENDARS 2 // 暦の種別の数

typedef unsigned char Calendar_t;
CalError_t
Calendrier ライブラリのエラー番号 (無符号整数).
typedef unsigned CalError_t;

#define CAL_OK                 0 // エラーなし.
#define CAL_E_INVALID_CALENDAR 1 // 暦の種別が無効.
#define CAL_E_INVALID_DATE     2 // 日付が無効.
#define CAL_E_INVALID_TIME     3 // 時刻が無効.
#define CAL_E_OVERFLOW         4 // 通算日数等の計算がオーバーフローした.

#define CAL_NERRORS            5 // エラー番号の総数
CalFDays_t
浮動小数型通算日数.
#ifdef CAL_USE_FLOAT
typedef double CalFDays_t;
#endif /* CAL_USE_FLOAT */
CalSecondDiv_t
通算秒数の除算結果 (商および剰余) を受け渡すための構造体.
(C標準ライブラリの div_t,ldiv_t の CalSeconds_t 版.)
typedef struct {
  CalSeconds_t quot, rem;
} CalSecondDiv_t;
CalSecondOfDay_t
日内通算秒数または1日の秒数 (0 〜 CAL_MAXSECONDSINADAY) を表すのに十分 (17ビット以上) で, 処理系にとって効率の良い無符号整数型. デフォルトでは unsigned 型 (それがビット数不足ならば unsigned long 型) として定義される.
#ifdef UINT_MAX
#if UINT_MAX >= CAL_MAXSECONDSINADAY
typedef unsigned CalSecondOfDay_t;
#else /* UINT_MAX >= CAL_MAXSECONDSINADAY */
typedef unsigned long CalSecondOfDay_t;
#endif /* UINT_MAX >= CAL_MAXSECONDSINADAY */
#else /* UINT_MAX */
// UINT_MAX が定義されていない処理系の場合:
// 0〜CAL_MAXSECONDSINADAY の範囲を表すのに十分な無符号整数型を指定する.
//typedef unsigned CalSecondOfDay_t;
typedef unsigned long CalSecondOfDay_t;
#endif /* UINT_MAX */
CalSeconds_t
通算秒数または秒数 (差) を表す符号付整数型. 通常,4バイト以上の符号付整数型を使用する.
typedef long CalSeconds_t;  // デフォルトの定義 (変更可能)
CalTime_t
時刻を表す構造体.
typedef struct {
  unsigned char hour;   // 時 (0〜23)
  unsigned char minute; // 分 (0〜59)
  unsigned char second; // 秒 (0〜60 (閏秒の場合))
} CalTime_t;
CalYear_t
年を表す符号付整数型 (普通は2バイト以上あれば十分).
typedef int CalYear_t;  // デフォルトの定義 (変更可能)

7.更新履歴

  1. 2008/11/19(水) 暫定版公開
  2. 2008/12/20(土) Ver.1.0 公開


Copyright © 2008 noocyte, All rights reserved.
E-mail: relipmoced (a) yahoo.co.jp
  (" (a) " を半角のアットマークに書き替えてください.)
リンクはご自由に.