Hatena::Groupcprogramming

Going My C Way このページをアンテナに追加 RSSフィード

2011年07月21日(木)

2000年1月1日からの経過日数から年月日を求める。

| 19:40 |  2000年1月1日からの経過日数から年月日を求める。 - Going My C Way を含むブックマーク はてなブックマーク -  2000年1月1日からの経過日数から年月日を求める。 - Going My C Way  2000年1月1日からの経過日数から年月日を求める。 - Going My C Way のブックマークコメント

2000年1月1日からの経過日数を求める - Going My C Way - C言語プログラミング【mattari();】 に追加。

to_date() は 2000年1月1日 を 0日目とする経過日数(elapsed_days)から年月日を求める。対応期間は、2000年1月1日〜2049年12月31日。

追加するコード

#define ABOUT_DAYS_OF_MONTH (30)

int to_date(int elapsed_days, int *year, int *month, int *day)
{
    int y4 = elapsed_days / DAYS_OF_4YEARS;
    int d0 = elapsed_days % DAYS_OF_4YEARS;
    int m0 = d0 / ABOUT_DAYS_OF_MONTH;
    int m1 = m0 - (d0 < days[m0]);

    if (year) {
        *year = EPOCH_YEAR + (y4 * 4) + (m1 / MONTHS_OF_YEAR);
    }
    if (month) {
        *month = (m1 % MONTHS_OF_YEAR) + 1;
    }
    if (day) {
        *day = (d0 - days[m1]) + 1;
    }

    return elapsed_days;
}

days テーブルを変更する必要がある。(48月目のデータを追加する)

/* 閏年の1月から3年後の12月まで、その月の1日での経過日数 */
static const int days[] = {
/*   1月   2月   3月   4月   5月   6月   7月   8月   9月  10月  11月  12月 */
/*閏*/ 0,   31,   60,   91,  121,  152,  182,  213,  244,  274,  305,  335,
     366,  397,  425,  456,  486,  517,  547,  578,  609,  639,  670,  700,
     731,  762,  790,  821,  851,  882,  912,  943,  974, 1004, 1035, 1065,
    1096, 1127, 1155, 1186, 1216, 1247, 1277, 1308, 1339, 1369, 1400, 1430,
    1461,  /* <-- これを追加 */
};

以下のような main() でテストしてみた。

int main(void)
{
    int days;

    for (days = 0; days < 1500; days++) {
        to_date(days, &year, &month, &day);

        printf("%5d = %04d/%02d/%02d\n", days, year, month, day);
    };

    return EXIT_SUCCESS;
}

結果。

    0 = 2000/01/01
    1 = 2000/01/02
    2 = 2000/01/03
    3 = 2000/01/04
    4 = 2000/01/05
    5 = 2000/01/06
    6 = 2000/01/07
    7 = 2000/01/08
         :
   57 = 2000/02/27
   58 = 2000/02/28
   59 = 2000/02/29
   60 = 2000/03/01
   61 = 2000/03/02
   62 = 2000/03/03
         :
  364 = 2000/12/30
  365 = 2000/12/31
  366 = 2001/01/01
  367 = 2001/01/02
         :
 1458 = 2003/12/29
 1459 = 2003/12/30
 1460 = 2003/12/31
 1461 = 2004/01/01
 1462 = 2004/01/02
 1463 = 2004/01/03
         :

OK。