本稿は Python 版と同様の理由で記述しています。
日付の加減算を装備していない他言語への実装や、学習のために本稿を参考にしてください。
Java で MJD の加減算をするには以下のように簡単に記述できます。
LocalDate は紀元前も扱えるため (ほぼ) 制限がありません。(最大で -10 億年 ~ +10 億年ぐらいの年月日)
import java.time.LocalDate; import java.time.temporal.JulianFields; // LocalDate を使った MJD : グレゴリオ年月日 → MJD LocalDate date1 = LocalDate.of(2023,10,10); long mjd1 = date1.getLong(JulianFields.MODIFIED_JULIAN_DAY); // MJD へ変換する。 System.out.printf("date1 %d-%d-%d: %d\n", date1.getYear(), date1.getMonthValue(), date1.getDayOfMonth(), mjd1); // 結果を表示する。 // LocalDate を使った MJD : MJD → グレゴリオ年月日 long mjd2 = 60227 - 10950; // 49277: 2023-10-10 の 10950 日前 LocalDate setter = LocalDate.MIN; // MIN / MAX どちらでも使用可。 LocalDate date2 = setter.with(JulianFields.MODIFIED_JULIAN_DAY, mjd2); // LocalDate へ変換する。 System.out.printf("date2 %d-%d-%d: %d\n", date2.getYear(), date2.getMonthValue(), date2.getDayOfMonth(), mjd2); // 結果を表示する。
実行結果 date1 2023-10-10: 60227 date2 1993-10-17: 49277
扱える範囲は -999999999-01-01 ~ +999999999-12-31
import java.time.LocalDate; System.out.println(LocalDate.MIN); System.out.println(LocalDate.MAX);
実行結果 -999999999-01-01 +999999999-12-31
日付の加減算に関する問題
問題は省略します。
Java のプログラムを扱っている人なら、日付計算の煩雑さも理解しているはずなので。
気になる人は、Python 版か十進 BASIC 版を参照してください。
Java で実装
アルゴリズムは Wikipedia からのパクリです。
Mjd.java
import static java.lang.Math.floor; /* * Mjd.java version 1.0 written by fuku@rouge.gr.jp * * 修正ユリウス日 / グレゴリオ暦 の相互変換を行う。 * * https://ja.wikipedia.org/wiki/ユリウス通日#修正ユリウス日(MJD) * より。 */
public class Mjd { /** * グレゴリオ暦 Y,M,D → MJD の変換 * @param y 年 * @param m 月 * @param d 日 * @return MJD の値 */ public static double greg2mjd(int y, int m, float d) { if(m <= 2) { m += 12; y -= 1; } return floor((365 + 1/4.0) * y) + floor(y / 400.0) - floor(y / 100.0) + floor(30.59 * (m - 2)) + d - 678912; }
/** * ユリウス暦 → MJD の変換 * @param y 年 * @param m 月 * @param d 日 * @return MJD の値 */ public static double jd2mjd(int y, int m, float d) { if(m <= 2) { m += 12; y -= 1; } return floor(365.25 * y) + floor(30.59 * (m-2)) + d - 678914; }
/** * MJD → ユリウス暦 の変換 * @param days MJD の値 * @return y,m,d ユリウス暦 */ public static double[] mjd2jd(double days) { double n = days + 678883; double a = 4 * n + 3; double b = 5 * floor((a % 1461) / 4) + 2; double y = floor(a / 1461); double m = floor(b / 153) + 3; double d = floor((b % 153) / 5) + 1; if(m > 12) { m -= 12; y += 1; } return new double[]{y,m,d}; }
/** * MJD → グレゴリオ暦 の変換 * @param days MJD の値 * @return y,m,d グレゴリオ暦 */ public static double[] mjd2greg(double days) { double n = days + 678881; double a = 4 * n + 3 + 4 * floor(3 / 4.0 * floor(4 * (n + 1) / 146097 + 1)); double b = 5 * floor((a % 1461) / 4) + 2; double y = floor(a / 1461); double m = floor(b / 153) + 3; double d = floor((b % 153) / 5) + 1; if(m > 12) { m -= 12; y += 1; } return new double[]{y,m,d}; }
/** * MJD → 曜日 の変換 * @param days MJD の値 * @return 曜日 (0:水曜 1:木曜 .. 6:火曜) */ public static double mjd2week(double days) { return days % 7; }
/** * MJD → 十二支 の変換 * @param days MJD の値 * @return 十二支 (0:寅 1:卯 2:辰 .. 11:丑) */ public static double mjd2zodiac(double days) { return days % 12; }
/** * MJD → 十干 の変換 * @param days MJD の値 * @return 十干 (0:甲 1:乙 2:丙 .. 9:癸) */ public static double mjd2stems(double days) { return days % 10; } }