儒略日
儒略日是自 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.5
18: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.UTC
,Javascript 确实有,它将以 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 }