如何将 Java 中的 D M Y HH:MM:SS 字符串转换为儒略日期?

How to convert a D M Y HH:MM:SS string in Java to Julian Date?

我在 Java 中有一些字符串,格式如下:日月年 Hour:Minute:Second

7 Jan 2010 23:00:00.000
4 Feb 2010 17:40:00.000

解析此字符串并将值转换为生成的儒略日期的最简单方法是什么?我正在从 Excel 中读取这些字符串,因此它们不是具有任何类型 conversion/formatting 实用程序的对象(只是原始字符串)。是否有一个简单的库或函数可以调用来转换这些,或者我是否必须手动编写解析器?谢谢

java.time

当然,Java 有一个内置的日期和时间解析器,DateTimeFormatter class(如此命名是因为它还可以将日期和时间格式化回字符串) .还有一些 classes 可以利用它来生成自己的对象。在您的情况下,您需要 LocalDateTime class。 LocalDateTime 是没有时区或与 UTC 的偏移量的日期和时间,因此适合保存字符串中的数据。

此格式化程序适合您的字符串:

private static final DateTimeFormatter FORMATTER
        = DateTimeFormatter.ofPattern("d MMM uuuu HH:mm:ss.SSS", Locale.ENGLISH);

编辑:您在评论中写道:

Plugging in Jan 7 2010 hour 23 into this calculator: aavso.org/jd-calculator gives back 2455204.45833. Would this be the exact Julian Date? I believe your solution was giving the Day instead of Date decimal value

是的,没错。获取包含分数的儒略日期的修改代码为:

    String source = "7 Jan 2010 23:00:00.000";
    
    LocalDateTime ldt = LocalDateTime.parse(source, FORMATTER);
    // Subtract half a day to compensate for the
    // fact that the Julian day begins at noon
    LocalDateTime dateToUseForJulianDay = ldt.minusHours(12);
    long julianDayNumber = dateToUseForJulianDay.getLong(JulianFields.JULIAN_DAY);
    double juianDateFraction = (double) dateToUseForJulianDay.getLong(ChronoField.NANO_OF_DAY)
            / (double) Duration.ofDays(1).toNanos();
    double julianDate = julianDayNumber + juianDateFraction;
    
    System.out.println("Julian date: " + julianDate);

本例中的输出为:

Julian date: 2455204.4583333335

它与您从在线计算器中引用的结果非常吻合。

儒略日数是从公元前 4713 年 1 月 1 日开始的日期。儒略日从中午开始,Java 没有考虑这一点,所以我减去 12 小时来补偿并获得一天中所有时间的正确日期。由于 getLong() 方法只获取儒略日数作为整数,我需要单独找到分数。这是将一天中的纳秒除以一天中的纳秒总数的问题。从最初的日期和时间开始,我们需要从中午 12 点开始的纳米数量;但是因为我已经减去 12 小时,所以一天中的纳秒,从 0:00 午夜开始,就是我们需要的数字。

进一步 link:维基百科Julian day

我的图书馆 Time4J supports Julian Dates 开箱即用。

    ChronoFormatter<PlainTimestamp> f =
        ChronoFormatter.ofTimestampPattern(
            "d MMM uuuu HH:mm:ss.SSS", PatternType.CLDR, Locale.ENGLISH);
    Moment j2000 = f.parse("7 Jan 2010 23:00:00.000").atUTC(); // are your timestamps really UTC?
    // eventually also: ".in(Timezone.ofSystem());"

    System.out.println(JulianDay.ofSimplifiedTime(j2000)); // programmer's standard
    // JD(POSIX)2455204.4583333335
    System.out.println(JulianDay.ofEphemerisTime(j2000)); // astronomical definition
    // JD(TT)2455204.459099352

优点:

  • 不用自己复杂的计算。
  • 支持时间尺度 TT 的天文定义。
  • 明确显示时区依赖性(无论您选择什么)。