【ユリウス日サンプルプログラム】
ユリウス日⇔日付、曜日のサンプルプログラムです。

・ソース
/*
*************************************************
*                                                *
*        Julian <-> date program                    *
*                                                *
*************************************************
*/
/*
    JD    -> help
    JD JD -> JD to Date
    JD yyy mm dd -> Date to JD

*/

#include <stdio.h>
#include <stdlib.h>
#include <math.h>

double julian(int nYear, int nMonth, double dDay)
{
    double da, db;
    double dJD;

    if (nMonth < 3){
        nMonth += 12;
        nYear--;
    }

    // Calc. body
    da = floor(nYear/100.0);
    db = 2.0 - da + floor(da / 4.0);
    dJD = floor(365.25 * nYear) + floor(30.6001 * (nMonth + 1)) + dDay + db + 1720994.5;

    if (dJD < 2299160.5){
        dJD -= db;
    }

    return dJD;
}

void juian_date(double dJD, int *nYear, int *nMonth, double *dDay)
{
    int nY, nM;
    double da, db, dd;
    double dJDs = dJD + 0.5;
    double dJDi = floor(dJDs);
    double dJDf = dJDs - dJDi;

    if (dJDi > 2299160.0){
        da = floor((dJDi - 1867216.25) / 36524.25);
        dJDi += (1.0 + da - floor(da / 4.0));
    }

    db = dJDi + 1524.0;
    nY = (int)(floor((db - 122.1) / 365.25));
    dd = db - floor(nY * 365.25);
    nM = (int)(floor(dd / 30.6001));

    // Write Day
    *dDay = dd - floor(nM * 30.6001) + dJDf;

    // Write Month
    if (nM < 14){
        *nMonth = nM - 1;
    }else{
        *nMonth = nM - 13;
    }

    // Write Year
    if (*nMonth > 2){
        *nYear = nY - 4716;
    }else{
        *nYear = nY - 4715;
    }
}

int jd_week(double dJD)
{
    int nJD = (int)floor(dJD + 0.5);
    int nWeek = nJD % 7;
    if (nWeek < 0){
        nWeek += 7;
    }

    return nWeek;
}

int main(int argc, char *argv[])
{
    int nYY = 0;
    int nMM = 1;
    int nWeek;
    double dDay = 1.0;
    double dJD;

    char *pWeek[] = {"MON", "TUE", "WED", "THU", "FRI", "SAT", "SUN"};
   
    /* argc == 2 JD to Date */
    if (argc == 2){
        dJD = atof(argv[1]);
        juian_date(dJD, &nYY, &nMM, &dDay);
        nWeek = jd_week(dJD);
        printf("%f = %d/%d/%f(%s)\n", dJD, nYY, nMM, dDay, pWeek[nWeek]);
        return 0;
    }

    /* argc > 2 Date to JD */
    if (argc >= 3){
        nYY = atoi(argv[1]);
        nMM = atoi(argv[2]);
        if (argc >= 4){
            dDay = atof(argv[3]);
        }
        dJD = julian(nYY, nMM, dDay);
        nWeek = jd_week(dJD);
        juian_date(dJD, &nYY, &nMM, &dDay);
        printf("%d/%d/%f(%s) = %f\n", nYY, nMM, dDay, pWeek[nWeek], dJD);
        return 0;
    }

    /* Help */
    puts ("JD to Date ---> A>JD julian");
    puts ("Date to JD ---> A>JD year month day");
    return -1;
}

ソース(jd.c)download

・コンパイル
このサンプルは、コンソール用アプリです。
Linuxの場合は、ターミナルから
$ gcc -lm jd.c -ojd

Windowsの場合、VisualStudioの「Win32コンソール」で
プロジェクトにjd.cを登録してコンパイルして下さい。

他の環境でも、一般的なCなのでコンパイルできると思います。

実行は、Linuxならターミナルから起動。
Windowsの場合は、DOS窓から起動。

・使用例
日付→ユリウス日
日付は半角スペースで区切って
年 月 日を入れて起動。

jd 2016 9 8.8
2016/9/8.800000(THU) = 2457640.300000

日付チェックは行っていません。
ありえない日付の場合の動作は不明です。


ユリウス日→日付
ユリウス日だけを書いて起動して下さい。

jd 2457640.3
2457640.300000 = 2016/9/8.800000(THU)

どちらにしても、結果にJD、日付、曜日が出ます。


・デバッグ
デバッグ済みですが、確認のためにやってみましょう。

1)逆変換
日付→JDを行い、そのJDで元の日付になるか?
jd 2016 9 8.8
2016/9/8.800000(THU) = 2457640.300000
jd 2457640.3
2457640.300000 = 2016/9/8.800000(THU)

2)起点のTEST
jd 0
0.000000 = -4712/1/1.500000(MON)
紀元前4713年1月1日のお昼

3)ユリウス暦、グレゴリオ暦の境目
jd 2299159.5
2299159.500000 = 1582/10/4.000000(THU)
jd 2299160.5
2299160.500000 = 1582/10/15.000000(FRI)
1582年10月4日(ユリウス暦)の次が
10月15日(グレゴリオ暦)

4)閏年のチェック
d 1500 2 29
1500/2/29.000000(SAT) = 2268991.500000
1500年はユリウス暦なので閏年
『ユリウス暦は、4で割れる年はすべて閏年』

jd 1600 2 29
1600/2/29.000000(TUE) = 2305506.500000
1600年は閏年

jd  1700 2 29
1700/3/1.000000(MON) = 2342031.500000
1700年はグレゴリオ暦なので平年
よって、2月29日が3月1日になる。
『グレゴリオ暦は、
100で割切れ、400で割切れない年は平年』


以上、著作権は放棄しますので、
使ってみようと思われる方は自由に使ってください。

inserted by FC2 system