在javascript中计算Jday(儒略日)

IT技术 javascript jquery
2021-02-01 17:16:34

我需要jday在 javascript 中进行计算,以便进行客户端验证,任何人都可以帮助我如何JDAY在 javascript 或脚本中计算以将给定的 JDAY 更改为实际日期,反之亦然。

要知道什么是 JDay,我找到了以下网站,

http://www.pauahtun.org/Software/jday.1.html

我也参考以下网站进行计算,这是在 JAVA 中提到的

http://www.rgagnon.com/javadetails/java-0506.html

先感谢您

6个回答

儒略日

儒略是自 7980 年循环开始以来经过的天数。

该系统由 Joseph Scaliger 于 1583 年发明,其目的是使计算一个日历日期和另一个日历日期之间的整数整数差异变得容易

7980 年周期是通过结合几个传统时间周期(太阳、月球和特定的罗马税收周期)得出的,其中 7980 是公倍数。

第一个儒略周期的起点开始于公元前 4713 年 1 月 1 日格林威治标准时间中午,并将于格林威治标准时间 3268 年 1 月 22 日中午结束,正好是整整 7980 天之后。

例如,2016 年 1 月 1 日的儒略日数是 2,457,389,这是自公元前 4713 年 1 月 1 日以来的天数。

如何计算

正如我们所知,Unix 时间是自 1970 年 1 月 1 日 00:00:00 UTC 以来的秒数,不计算闰秒,也称为 Epoch,当我们已经拥有 Unix 时,我们可以使用一些数学方法来计算儒略日时间。

GMT 和 UTC 在实践中共享相同的当前时间,因此对此,应该没有区别。

首先,我们需要知道从儒略周期开始到 Unix 时间戳开始的天数。
换句话说,从公元前 4713 年 1 月 1 日 12:00:00 GMT 到 1970 年 1 月 1 日 00:00:00 UTC 的天数。

有了这个永远不会改变的天数,我们可以添加从 1970 年 1 月 1 日到今天的天数,无论如何,这是 Javascript 返回的天数,以获得儒略日。

没有把所有这些年加起来,只是通过搜索网络,它告诉我们公元前 4713 年和公元 1970 年之间的天数差异是 2440588 天,并且因为朱利安循环开始于中午,而不是午夜,我们必须减去半天,使其成为 2440587.5 天。

所以我们现在拥有的是 2440587.5 days + UNIX TIME in days === Julian Day

通过一些简单的数学运算,我们可以计算出一天的长度为 86,400 秒,而使用 Javascript 时 Unix 时间戳以毫秒为单位,因此UNIX TIME / 86400000可以得到从 1970 年 1 月 1 日星期四到今天的天数。

现在就这一天而言,我们想要的是整数天数,而不是小数,可以将其四舍五入到一整天的收盘价,做类似的事情

Math.floor((UNIX TIME / 86400000) + 2440587.5);

朱利安日期

有时在编程中,“儒略日期”已开始表示自一年开始以来的天数,例如 2016 年 6 月 1 日将是该年的 152 天等。

“儒略日期”的正确用法是将时间戳添加为一天的小数部分的儒略日。

以本答案顶部的示例为例,其中 2016 年 1 月 1 日是儒略日 2,457,389,我们可以为此添加一个时间。
儒略日从中午开始,没有添加小数时间,因此在午夜2457389.518:00 或中午后 6 小时,将是2457389.25,添加“半天”、“一天的四分之一”等.

再计算一下

这意味着 0.1 Julian Date 等于 24 小时除以 10,或者24 / 10 === 2.4 hours换句话说,Julian Day 时间戳是带小数的小数(一天的十分之一等)

让我们看看一些 Javascript 函数,首先是Date构造函数。

Javascript 只能访问它运行的计算机上的本地时间,因此当我们这样做时,new Date()它并不一定要创建 UTC 日期,即使 UNIX 时间是 UTC,也会new Date为您提供从纪元到计算机本地时间的秒数有,并且不考虑您的时区。

然而Date.UTCJavascript 确实有,它将以 UTC 格式返回日期,让我们检查差异,这当然会根据您将本地系统设置为的时区而有所不同。

var regular_date = new Date(2016, 1, 1, 0, 0, 0);
var UTC_date     = Date.UTC(2016, 1, 1, 0, 0, 0);
var difference   = UTC_date - regular_date;

document.body.innerHTML = 'The difference between your local time and UTC is ' +(difference/1000)+ ' seconds';

记住本章开头的部分,大约 0.1 Julian Date 等于 24 小时除以 10,或者24 / 10 === 2.4 hours,好吧,2.4 小时是 144 分钟,现在让我们快速看一下 JavascriptsgetTimezoneOffset()方法,文档说

getTimezoneOffset() 方法返回当前语言环境相对于 UTC 的时区偏移量(以分钟为单位)。

因此,它以分钟为单位返回系统时区的偏移量,这很有趣,因为大多数处理日期的 javascript 方法返回毫秒。

我们知道一天的 1/10 是 144 分钟,因此 10/10 或一整天将是 1440 分钟,因此我们可以使用一些数学方法来抵消以分钟为单位的本地系统时区,然后将其除以一天中的分钟数,以获得正确的小数值

所以现在我们有

2440587.5 days + UNIX TIME in days === Julian Day

我们知道 Javascripts Date 构造函数并没有真正使用 UTC 作为当前日期,而是系统时间,所以我们必须有

TIMEZONEOFFSET / 1440

将他们联合起来,我们会得到

(JAVASCRIPT TIME / 86400000) - (TIMEZONEOFFSET / 1440) + 2440587.5
//  ^^ days since epoch ^^      ^^ subtract offset ^^    ^^days from 4713 B.C. to 1970 A.D.

将其转换为 javascript 将是

var date = new Date();     // a new date
var time = date.getTime(); // the timestamp, not neccessarely using UTC as current time

var julian_day = (time / 86400000) - (date.getTimezoneOffset()/1440) + 2440587.5);

现在这也是我们应该用来获取儒略日的方法,采取措施去除时区偏移,当然没有儒略日期的小数时间部分
我们将通过简单地将其四舍五入到最接近的整数来做到这一点

var julian_date = Math.floor((time / 86400000) - (date.getTimezoneOffset()/1440) + 2440587.5));

现在是我对这个问题的原始答案的时候了,在我进行了非常长的编辑以解释为什么这是正确的方法之前,在评论字段中投诉之后。

Date.prototype.getJulian = function() {
  return Math.floor((this / 86400000) - (this.getTimezoneOffset() / 1440) + 2440587.5);
}

var today = new Date(); //set any date
var julian = today.getJulian(); //get Julian counterpart

console.log(julian)
.as-console-wrapper {top:0}

而同样该fracional部分

Date.prototype.getJulian = function() {
  return (this / 86400000) - (this.getTimezoneOffset() / 1440) + 2440587.5;
}

var today = new Date(); //set any date
var julian = today.getJulian(); //get Julian counterpart

console.log(julian)
.as-console-wrapper { top: 0 }

最后,一个说明原因的例子

new Date().getTime()/86400000 + 2440587.5

不起作用,至少如果您的系统时间设置为具有偏移量的时区,即 GMT 以外的任何其他时间,则不起作用

// the correct approach
Date.prototype.getJulian = function() {
    return (this / 86400000) - (this.getTimezoneOffset() / 1440) + 2440587.5;
}

// the simple approach, that does not take the timezone into consideration
Date.prototype.notReallyJulian = function() {
  return this.getTime()/86400000 + 2440587.5;
}
// --------------

// remember how 18:00 should return a fractional 0.25 etc
var date = new Date(2016, 0,    1,   18,   0,   0,    0); 
//                   ^    ^     ^     ^    ^    ^     ^
//                 year  month date  hour min  sec  milli
                   
var julian = date.getJulian();       //get Julian date
var maybe  = date.notReallyJulian(); // not so much

console.log(julian); // always returns 2457389.25
console.log(maybe);  // returns different fractions, depending on timezone offset
.as-console-wrapper { top: 0 }

这是不正确的。不需要,(this.getTimezoneOffset() / 1440)因为Date.getTime()已经返回 UTC 时间戳。
2021-03-27 17:16:34
@JamesMcCormac - 我已经编辑了答案,以准确解释发生了什么,以及为什么我的答案包括时区,这实际上是正确的方法,并返回 UTC Julian Date,尽管有些人似乎并没有真正理解它.
2021-03-31 17:16:34
答案中有一个解释,并附加了一个示例,表明Date().getTime()无法正常工作?这工作正常,但 Christophe Bouchon 似乎是正确的,某些浏览器在夏令时存在一些问题并将正确的 iana 规则应用于较旧的日期等。
2021-04-02 17:16:34
不知情的读者的注意事项(就像我昨天一样):这个答案给出了一个整数本地儒略日期(比如 2456483);Wilbert 的回答给出了一个 UTC Julian Date,包括代表一天中时间的分数(如 2456483.8500826736)。
2021-04-11 17:16:34
Wilberts 的回答给出了正确的值,但不包括有关时区的信息。儒略日应以 UTC 计算。
2021-04-12 17:16:34

new Date().getTime()/86400000 + 2440587.5 将获取unix时间戳,将其转换为天并添加1970-01-01的JD,这是unix时间戳的纪元。

这就是天文学家所说的朱利安日期。它定义明确。由于 Unix 时间戳和 JD 都没有考虑闰秒,因此不会降低准确性。请注意,JD 不需要在 UTC 时区(但通常是)。这个答案为您提供了 UTC 时区的 JD。

什么是.52440587.5的呢?
2021-03-18 17:16:34
.5 是导致京东在中午开始的半天偏移量。天文学家使用这个系统来防止他们的日期在夜间观测期间发生变化。
2021-03-22 17:16:34

根据维基百科

a = (14 - month) / 12
y = year + 4800 - a
m = month + 12a - 3
JDN = day + (153m + 2) / 5 + 365y + y/4 - y/100 + y/400 - 32045

如果您在实施方面遇到更具体的问题,请在问题中提供这些详细信息,以便我们进一步提供帮助。

注意:这是不正确的,因为这里忘记了 Wiki 上的“地板括号”。

正确的公式是:

a = Int((14 - Month) / 12)
y = Year + 4800 - a
m = Month + 12 * a - 3
JDN = Day + Int((153 * m + 2) / 5) + 365 * y + Int(y / 4) - Int(y / 100) + Int(y / 400) - 32045
像魅力一样工作。我在 Typescript 上使用了 Math.floor 而不是 Int。
2021-04-05 17:16:34

似乎接受的答案中给出的最终代码是错误的查看美国海军天文台网站上的“官方”在线计算器:

http://aa.usno.navy.mil/data/docs/JulianDate.php

如果有人知道答案时间和日历的正确答案,那就是 USNO。

这是一个断开的链接。您可能会看到时区日期与 UTC 日期/时间之间的差异。
2021-04-06 17:16:34

JD =>

const millisecondsSince1970Now = new Date+0
const julianDayNow = 2440587.5+new Date/864e5
const dateNow = new Date((julianDayNow-2440587.5)*864e5)

关于什么是儒略日以及如何计算儒略日似乎存在混淆

Javascript 时间以 GMT/UTC 毫秒 UInt64 从Jan 1, 1970 at midnight.

JavaScriptDate函数的月、日、年方面都是使用公历规则实现的。但 Julian “Days” 不受此影响;然而,将“天数”映射到儒略月、日、年将是。

因此,计算儒略日转换是从该时间点(格林威治标准时间 1970 年 1 月 1 日/UTC 格里高利)算起的相对天数。

儒略日为Jan 1, 1970IS 2440587.5(0.5因为JulianDays中午开始)。

864e5常数是JavaScript的记法86,400,000(毫秒/天)。

唯一的复杂性是在采用 1582 年格里高利历法之前计算儒略历日期(天),教皇格里高利要求对其进行更改以纠正影响复活节的闰年漂移误差。直到 1752 年左右,世界上大多数使用儒略历系统或派生系统的国家才完全采用(俄罗斯和中国直到 20 世纪)

而在朱利安日期实施的前 60 年中更严重的错误来自于公元前 46 年的朱利叶斯凯撒“改革”任务,其中牧师在折叠 14/15 月历时犯了错误,人们误解了他们。(因此在那个时期的许多宗教日期和时间都存在错误)

🎪 其中没有一个适用于儒略日值的 JavaScript 计算。

另见:(来自 AfEE EdgeS/EdgeShell 脚本核心笔记)

有一个单独的微妙“闰秒”适用于天文计算和与地球轨道路径和旋转漂移有关的原子钟的使用。

即,86,400.000每天的秒数需要“调整”以保持日历(时区、GPS 卫星)与当前保持同步86,400.002

#### 相关 - “如何在 JavaScript 中创建 GUID / UUID” <br> - 包含JavaScript中的julian day时间转换
2021-03-22 17:16:34