Convert a Julian Date to an Instant

前端 未结 4 1511
再見小時候
再見小時候 2021-01-05 14:58

I\'m running into a situation where I would like to convert from a Julian date to an java.time.Instant (if that makes sense), or some Java time that can be more easily under

4条回答
  •  醉梦人生
    2021-01-05 15:21

    Here is a solution using the new Java 8 classes:

    public class JulianDay {
        private static final double NANOS_PER_DAY = 24.0 * 60.0 * 60.0 * 1000000000.0;
    
        // Calculate Instants for some epochs as defined in Wikipedia.
        public static final Instant REDUCED_JD =
                ZonedDateTime.of(1858, 11, 16, 12, 0, 0, 0, ZoneOffset.UTC).toInstant();
        public static final Instant MODIFIED_JD =
                ZonedDateTime.of(1858, 11, 17, 0, 0, 0, 0, ZoneOffset.UTC).toInstant();
        public static final Instant JULIAN_DATE =
                REDUCED_JD.minus(2400000, ChronoUnit.DAYS);
    
        private final Instant epoch;
    
        public JulianDay(Instant epoch) {
            super();
            this.epoch = epoch;
        }
    
        public Instant toInstant(double day) {
            long l = (long) day;
            return epoch
                    .plus(l, ChronoUnit.DAYS)
                    .plusNanos(Math.round((day - l) * NANOS_PER_DAY));
        }
    
        public static void main(String[] args) {
            // Use the example values from Wikipedia for 2015-09-07 13:21 UTC.
            System.out.println(new JulianDay(REDUCED_JD).toInstant(57273.05625));
            // Output: 2015-09-07T13:21:00.000000126Z
            System.out.println(new JulianDay(MODIFIED_JD).toInstant(57272.55625));
            // Output: 2015-09-07T13:21:00.000000126Z
            System.out.println(new JulianDay(JULIAN_DATE).toInstant(2457273.05625));
            // Output: 2015-09-07T13:20:59.999991953Z
        }
    }
    

    Regarding the JulianFields you asked about, you can define a custom formatter like this:

    DateTimeFormatter formatter = new DateTimeFormatterBuilder()
        .appendValue(JulianFields.MODIFIED_JULIAN_DAY)
        .toFormatter().withZone(ZoneOffset.UTC);
    

    Unfortunately it doesn't support fractions of days:

    System.out.println(formatter.format(Instant.now())); // Output: 57249
    System.out.println(LocalDate.from(formatter.parse("57249"))); // Output: 2015-08-15
    

提交回复
热议问题