8

ユリウス日番号は、タイムスタンプを、UTC の 4713 年 1 月 1 日 BC の正午からの連続した日数 (および小数日) として表す手段です。Java 7 SE API には、この形式のサポートが含まれていません。SQLite データベースを使用した開発者は、strftime() 関数によって提供されるネイティブのユリウス日サポートを使用したことがあるかもしれません。

タイムスタンプをユリウス日番号として表す利点には、次のようなものがあります。

  • 日付と時刻は、プリミティブ データ型 (double) でミリ秒の精度で表すことができます。
  • 1 年の日数は、1 日の数秒よりもいくらか具体的です
  • この程度の精度が重要でない場合、「うるう秒」の問題を回避します
  • 日付間の日数の計算は簡単です。ソートの優先順位は簡単に決定されます
  • 非常に軽量

短所

  • Java Date/Time API には、JDN のサポートが組み込まれていません。
  • 非常に正確な時間測定には不向き
  • UTC に対してのみ定義され、UTC から現地時間にマップする必要があります
  • エンドユーザーへの表示には適していません。表示前に変換/フォーマットする必要があります

ユリウス日番号は天文計算で一般的に使用され、その定義は高度に標準化され、受け入れられています。同様に、修正ユリウス日番号 (1858 年 11 月 17 日 UTC の午前 0 時からカウント) は標準的に定義され、航空宇宙アプリケーションで使用されます ( http://tycho.usno.navy.mil/mjd.htmlを参照)。

日付/時刻演算または時系列ソートを多用するアプリケーションの場合 (または、タイムスタンプを保持するよりも軽量プリミティブを保持する方が魅力的である場合)、日付と時刻を内部的に JDN または MJD として表現することが理にかなっている場合があります。

次のコードは、Java Date/Time/Calendar API でのユリウス日番号または修正ユリウス日番号の使用を容易にする関数を定義します。このコードは、Jean Meeus の「Astronomical Algorithms」、第 1 版、1991 年に公開されたアルゴリズムに基づいています。

public class JulianDay {

    private static final int YEAR = 0;
    private static final int MONTH = 1;
    private static final int DAY = 2;
    private static final int HOURS = 3;
    private static final int MINUTES = 4;
    private static final int SECONDS = 5;
    private static final int MILLIS = 6;

    :
    :

    // Converts a timestamp presented as an array of integers in the following
    // order (from index 0 to 6): year,month,day,hours,minutes,seconds,millis
    // month (1-12), day (1-28 or 29), hours (0-23), min/sec (0-59) to a
    // Modified Julian Day Number.
    // For clarity and simplicity, the input values are assumed to be well-formed;
    // error checking is not implemented in the snippet.

    public static double toMJD(int[] ymd_hms) {

        int y = ymd_hms[YEAR];
        int m = ymd_hms[MONTH];
        double d = (double) ymd_hms[DAY];

        d = d + ((ymd_hms[HOURS] / 24.0) +
                 (ymd_hms[MINUTES] / 1440.0) +
                 (ymd_hms[SECONDS] / 86400.0) +
                 (ymd_hms[MILLIS] / 86400000.0));

        if (m == 1 || m == 2) {
            y--;
            m = m + 12;
        }

        double a = Math.floor(y / 100);
        double b = 2 - a + Math.floor(a / 4);

        return (Math.floor(365.25 * (y + 4716.0)) +
               Math.floor(30.6001 * (m + 1)) +
               d + b - 1524.5) - 2400000.5;  // for Julian Day omit the 2400000.5 term
    }

    // Converts an Modified Julian Day Number (double) to an integer array representing
    // a timestamp (year,month,day,hours,mins,secs,millis). Works for all positive JDN

    public static int[] toTimestamp(double mjd) {

        int ymd_hms[] = { -1, -1, -1, -1, -1, -1, -1 };
        int a, b, c, d, e, z;

        double jd = mjd + 2400000.5 + 0.5;  // if a JDN is passed as argument,
                                            // omit the 2400000.5 term
        double f, x;

        z = (int) Math.floor(jd);
        f = jd - z;

        if (z >= 2299161) {
            int alpha = (int) Math.floor((z - 1867216.25) / 36524.25);
            a = z + 1 + alpha - (int) Math.floor(alpha / 4);
        } else {
            a = z;
        }

        b = a + 1524;
        c = (int) Math.floor((b - 122.1) / 365.25);
        d = (int) Math.floor(365.25 * c);
        e = (int) Math.floor((b - d) / 30.6001);

        ymd_hms[DAY] = b - d - (int) Math.floor(30.6001 * e);
        ymd_hms[MONTH] = (e < 14)
                ? (e - 1)
                : (e - 13);
        ymd_hms[YEAR] = (ymd_hms[MONTH] > 2)
                ? (c - 4716)
                : (c - 4715);

        for (int i = HOURS; i <= MILLIS; i++) {
            switch(i) {
                case HOURS:
                    f = f * 24.0;
                    break;
                case MINUTES: case SECONDS:
                    f = f * 60.0;
                    break;
                case MILLIS:
                    f = f * 1000.0;
                    break;  
            }
            x = Math.floor(f);
            ymd_hms[i] = (int) x;
            f = f - x;
        }   

        return ymd_hms;
    }
}

この回答はここでも提供されています: How can I convert between a Java Date and Julian day number? . 現在の投稿では、アルゴリズムの参考文献がいくつかの議論とともに提供されています。上記のアルゴリズムの実装には、(Math 関数を除いて) Java API の依存関係も含まれていません。

4

3 に答える 3

0

コア JDK クラスの外に移動する意思がある場合は、Jodaが解決策になる可能性があります。Joda はユリウス暦システムをサポートしています。ドキュメントページから:

Chronology julianChrono = JulianChronology.getInstance();
DateTime dt = new DateTime(1066, 10, 14, 0, 0, 0, julianChrono);

それは、ユリウス暦で 1066 年のヘイスティングスの戦いです。

于 2013-02-20T19:56:26.470 に答える