如何解决Java - 计算儒略日数到公历日期和时间
最近我看到了一个不错的 javascript 库,它可以计算特定日期、纬度和经度的太阳时间。由于我想在我的一些 android 开发中使用它,我正在将该库重写为 java。 由于使用儒略日数而不是公历日期计算时间要容易得多,因此我必须将日期转换为儒略日期。但是要在某些事件发生时做出响应,我必须将儒略日数转换为公历日期和时间。
在 javascript 中,很容易在儒略日数之间进行转换。 javascript的计算如下:
var dayMS = 1000 * 60 * 60 * 24;
var J1970 = 2440588;
var J2000 = 2451545;
function toJulian(date) { return date.valueOf() / dayMs - 0.5 + J1970; }
function fromJulian(j) { return new Date((j + 0.5 - J1970) * dayMs); }
但是从儒略日数转换给我很多麻烦。我在java中的上述javascript版本是:
double dayMs = 1000 * 60 * 60 * 24;
double J1970 = 2440588;
double J2000 = 245154;
public double toJulian(LocalDateTime date) {
zoneddatetime zdt = date.atZone(ZoneId.of("Europe/Vienna"));
double result = zdt.toInstant().toEpochMilli(); //milliseconds since epoch
result = result / dayMs - 0.5 + J1970;
return result;
}
public String fromJulian(double jdn) {
System.out.println("fromJulian.jdn: " + jdn);
int jalpha,ja,jb,jc,jd,je,year,month,day;
double julian = jdn,decimal= jdn % 1;
ja = (int) julian;
if (ja>= JGREG) {
jalpha = (int) (((ja - 1867216) - 0.25) / 36524.25);
ja = ja + 1 + jalpha - jalpha / 4;
}
jb = ja + 1524;
jc = (int) (6680.0 + ((jb - 2439870) - 122.1) / 365.25);
jd = 365 * jc + jc / 4;
je = (int) ((jb - jd) / 30.6001);
day = jb - jd - (int) (30.6001 * je);
month = je - 1;
if (month > 12) month = month - 12;
year = jc - 4715;
if (month > 2) year--;
if (year <= 0) year--;
double dhour = decimal * 24;
int hour = (int) Math.round(dhour);
decimal = dhour % 1;
double dminute = decimal * 60;
int minute = (int) Math.round(dminute);
decimal = dminute % 1;
double dsecond = decimal * 60;
int second = (int) Math.round(dsecond);
LocalDateTime ldt = LocalDateTime.of(
year,day,hour,minute,second
);
DateTimeFormatter dtf = DateTimeFormatter.ofPattern("dd-MM-yyyy HH:mm:ss");
zoneddatetime zdt = zoneddatetime.of(ldt,ZoneId.of("UTC"));
return dtf.format(zdt);
}
javascript 和 java 中的 toJulian 方法给了我完全相同的值,但是在 fromJulian 的方法中,我以某种方式获得了一个日期,但完全错误。
示例
日期 = "2020 年 12 月 26 日 00:00:00"
Javascript: 将日期插入 toJulian 函数并将值 (2459209.4583333335
) 重新插入函数 fromJulian 返回 26 December 00:00:00
。
Java: 将日期插入 toJulian 函数并将值 (2459209.4583333335
) 重新插入函数 fromJulian 返回 25 December 11:00:00
。
这两天以来,我尝试了从儒略日数计算公历日期的不同方法,但从未达到预期的输出。我已将整个 Java 库上传到 github (https://github.com/stnieder/SunCalc_Java)。我希望有人能够帮助我解决我的问题。
解决方法
编辑:Java 对儒略日数有一个粗略的支持。它正确计算天数。它不像儒略日定义的那样在中午开始新的一天,也不支持一天中的一小部分。我们仍然可以使用支持并自行进行适当的调整。
据我所知,以下方法进行了前后一致的转换,并同意您从 JavaScript 中的 toJulian()
获得的儒略日数。
private static final double dayMs = Duration.ofDays(1).toMillis();
public static double toJulian(LocalDateTime date) {
LocalTime timeOfDay = date.toLocalTime();
double result = date.getLong(JulianFields.JULIAN_DAY);
result += timeOfDay.get(ChronoField.MILLI_OF_DAY) / dayMs - 0.5;
return result;
}
public static LocalDateTime fromJulian(double jdn) {
LocalDate date = LocalDate.EPOCH.with(JulianFields.JULIAN_DAY,(long) jdn);
LocalDateTime result = date.atStartOfDay()
.plusHours(12)
.plus((long) (jdn % 1 * dayMs),ChronoUnit.MILLIS);
return result;
}
尝试一下:
LocalDateTime dateTime = LocalDateTime.of(2020,Month.DECEMBER,26,0);
double jdn = toJulian(dateTime);
System.out.println(jdn);
LocalDateTime convertedBack = fromJulian(jdn);
System.out.println(convertedBack);
System.out.println("Does it differ? " + Duration.between(dateTime,convertedBack));
输出:
2459209.5
2020-12-26T00:00
Does it differ? PT0S
最后一行包含PT0S
,一段0秒的时间,所以结果与起点没有区别。
文档链接: JulianFields.JULIAN_DAY
。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。