简体   繁体   English

如何在Java中将毫秒转换为Julian Day Number?

[英]How can I convert milliseconds to Julian Day Number in Java?

I need a Java method that converts from "elapsed milliseconds since the beginning of the Unix Epoch" to "Elapsed days since January 1, 4713 BC". 我需要一个Java方法,它从“自Unix时代开始以来经过的毫秒”转换为“自公元前4713年1月1日以来经过的天数”。 Is this functionality already implemented is Java? 这个功能已经实现了Java吗?

I have tried several options. 我尝试了几种选择。 Some of them don't compile. 其中一些不编译。 Some of them are incoherent with the conversions available on line ( http://www.onlineconversion.com/julian_date.htm ). 其中一些与在线可用的转换不一致( http://www.onlineconversion.com/julian_date.htm )。 So, please, post only answers that you have satisfactorily used yourselves. 那么,请发布您已经满意地使用自己的答案。

Try JDateTime from Jodd . 尝试JDateTimeJodd This is date-time class that performs all its calculations over Julian Date Numbers . 这是日期时间类,它对Julian Date Numbers执行所有计算。 JdateTime class has friendly user interface and any time you can get the value of Julian Date. JdateTime类具有友好的用户界面,只要您可以获得Julian Date的值。 For example, you can instantiate the class with epox milliseconds and then read the Julian Date Number: 例如,您可以使用epox毫秒实例化该类,然后读取Julian日期编号:

JDateTime jdt = new JDateTime(milliseconds);
JulianDateStamp jds = jdt.getJulianDate();
// or:
double jdn = jdt.getJulianDateDouble()
// or:
int jdn = jdt.getJulianDateNumber()

If you are interested in concrete calculation, see method TimeUtil#toJulianDate . 如果您对具体计算感兴趣,请参阅方法TimeUtil#toJulianDate It is based on proven astronomical algorithm, but it also takes care about calculation errors of floating-points. 它基于成熟的天文算法,但它也关注浮点的计算误差。 Thats why the result is JulianDateStamp , class that separately holds JD integer and its fraction, to provide precision up to 1 millisecond. 这就是为什么结果是JulianDateStamp ,这个类分别保存JD整数及其分数,以提供高达1毫秒的精度。 This class also has many test cases written. 该类还编写了许多测试用例。

The method posted here has essentially solved my needs: http://www.rgagnon.com/javadetails/java-0506.html#comment-811614512 You have to take in consideration that it returns the time at noon (12:00 UTC), which is one day later than the date at midnight (0:00 UTC). 这里发布的方法基本上解决了我的需求: http//www.rgagnon.com/javadetails/java-0506.html#comment-811614512您必须考虑到它在中午返回时间(12:00 UTC) ,比午夜(UTC时间0:00)的日期晚一天。

To convert from milliseconds to (year, month, day) - which is the format the aforementioned method expects -, you may use these instruccions: 要将毫秒转换为(年,月,日) - 这是上述方法所期望的格式 - ,您可以使用以下指令:

  Date date = new Date(longMillis);

  Calendar calendar = Calendar.getInstance();
  calendar.setTime(date);

  int year = calendar.get(Calendar.YEAR);
  int month = calendar.get(Calendar.MONTH) + 1; // El mes que devuelve Calendar va de 0 a 11.
  int day = calendar.get(Calendar.DAY_OF_MONTH);
  int[] ymd = new int[] {year, month, day};
    GregorianCalendar cal = new GregorianCalendar();
    cal.setTimeInMillis(millis);        
    cal.setGregorianChange(new Date(Long.MAX_VALUE));
    int julianDay = cal.get(Calendar.DAY_OF_YEAR);

tl;dr TL;博士

Instant.ofEpochMilli( millisSinceJavaEpoch )                   // Moment in UTC.
       .atOffset( ZoneOffset.UTC )                             // `OffsetDateTime` object.
       .getLong( java.time.temporal.JulianFields.JULIAN_DAY )  // `long` such as 2457811.

java.time java.time

Java 8 and later comes with the java.time classes, supplanting the troublesome old legacy date-time classes. Java 8及更高版本附带了java.time类,取代了麻烦的旧遗留日期时间类。 See Oracle Tutorial . 请参阅Oracle教程

"elapsed milliseconds since the beginning of the Unix Epoch" “从Unix Epoch开始以来经过的毫秒数”

If you mean the epoch of first moment of 1970 in UTC ( 1970-01-01T00:00:00Z ), then we can convert your count-of-milliseconds into a Instant object. 如果你的意思是1970年的第一个时刻的世纪( 1970-01-01T00:00:00Z ),那么我们可以将你的毫秒数转换成一个Instant对象。 The Instant class represents a moment on the timeline in UTC with a resolution of nanoseconds (up to nine (9) digits of a decimal fraction). Instant类表示UTC时间轴上的一个时刻,分辨率为纳秒 (最多九(9)位小数)。

long millisSinceJavaEpoch = Instant.now().toEpochMilli() ;  // Simulating your given number of milliseconds since 1970-01-01T00:00:00Z.

1488099298325 1488099298325

Instant instant = Instant.ofEpochMilli( millisSinceJavaEpoch );  // Convert from number to `Instant` object.

2017-02-26T08:54:58.325Z 2017-02-26T08:54:58.325Z

We need a date from that Instant . 我们需要一个Instant的日期。 I'm no expert on Julian chronology, but it seems that by convention people use UTC in mapping to the modern ISO 8601 chronology. 我不是Julian年表的专家,但似乎按照惯例,人们使用UTC映射到现代ISO 8601年表。 So let's convert that Instant to a OffsetDateTime with the offset constant ZoneOffset.UTC . 因此,让我们认为转换InstantOffsetDateTime与偏移常数ZoneOffset.UTC

OffsetDateTime odt = instant.atOffset( ZoneOffset.UTC );  // Convert from `Instant` to `OffsetDateTime` with UTC as assigned offset.

2017-02-26T08:54:58.325Z 2017-02-26T08:54:58.325Z

From the OffsetDateTime we can access a TemporalField . OffsetDateTime我们可以访问TemporalField As our implementation of TemporalField we want JULIAN_DAY constant from the java.time.temporal.JulianFields class. 作为我们的TemporalField实现,我们希望java.time.temporal.JulianFields类中的JULIAN_DAY常量。

long jd = odt.getLong( java.time.temporal.JulianFields.JULIAN_DAY );  // Convert to Julian Day (number of whole days since January 1, 4713 BCE in the Julian calendar, a.k.a. -4713-11-24 Gregorian).

2457811 2457811

This result matches the result given at the web site you mentioned . 此结果与您提到的网站上给出的结果相符。

See this code above run live at IdeOne.com . 请参阅上面的代码,在IdeOne.com上运行

Depending on your definition, you may want MODIFIED_JULIAN_DAY instead of JULIAN_DAY . 根据您的定义,您可能需要MODIFIED_JULIAN_DAY而不是JULIAN_DAY


About java.time 关于java.time

The java.time framework is built into Java 8 and later. java.time框架内置于Java 8及更高版本中。 These classes supplant the troublesome old legacy date-time classes such as java.util.Date , Calendar , & SimpleDateFormat . 这些类取代了麻烦的旧遗留日期时间类,如java.util.DateCalendarSimpleDateFormat

The Joda-Time project, now in maintenance mode , advises migration to the java.time classes. 现在处于维护模式Joda-Time项目建议迁移到java.time类。

To learn more, see the Oracle Tutorial . 要了解更多信息,请参阅Oracle教程 And search Stack Overflow for many examples and explanations. 并搜索Stack Overflow以获取许多示例和解释。 Specification is JSR 310 . 规范是JSR 310

Where to obtain the java.time classes? 从哪里获取java.time类?

The ThreeTen-Extra project extends java.time with additional classes. ThreeTen-Extra项目使用其他类扩展了java.time。 This project is a proving ground for possible future additions to java.time. 该项目是未来可能添加到java.time的试验场。 You may find some useful classes here such as Interval , YearWeek , YearQuarter , andfz more . 您可以在这里找到一些有用的课程,如IntervalYearWeekYearQuarter更多


org.threeten.extra.chrono.JulianChronology

Those java.time classes are extended by the ThreeTen-Extra project. 这些java.time类由ThreeTen-Extra项目扩展。 That project includes a proleptic implementation of the Julian calendar system, JulianChronology . 该项目包括proleptic实施的儒略历系统, JulianChronology

    Time time = new Time();
    time.setToNow();
    long currentTime = Long.parseLong("1484903678788");
    int currentJulianDay = Time.getJulianDay(currentTime, time.gmtoff);
    System.out.print(currentJulianDay); // 2457774

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM