【问题标题】:Calculating julian date with javascript用javascript计算朱利安日期
【发布时间】:2018-04-07 03:05:49
【问题描述】:

我正在尝试使用 javascript 从日历日期字符串计算儒略日期。我发现 this site 解释了如何计算它。

我制作了这个javascript代码:https://jsfiddle.net/kzgn8vs1/1/

var time = moment("2018-04-07 23:45:16 -0300", "YYYY-MM-DD HH:mm:ss Z").utc(); 
var Y = time.year();
var M = time.month() + 1;
var D = time.date() + moment.duration(time.format('HH:mm:ss')).asDays();

if( M == 1 || M == 2 ) {
    Y = Y - 1;
    M = M + 12;
}

var A = Y / 100;
var B = 2 - A + (A / 4);
var C = ( Y > 0 ) ? (365.25 * Y) : ((365.25 * Y) - 0.75);
var E = 30.6001 * (M + 1);

var JD = B+C+D+E+1720994.5;

console.log(JD);

返回 2458216.9802685184 日期为 2018-04-07 23:45:16 -0300。但是当我尝试一些在线转换器时,例如 http://www.onlineconversion.com/julian_date.htmhttps://www.aavso.org/jd-calculator

输入日期 2018-04-08 2:45:16(我的日期转换为 UTC),都返回 2458216.61477。与我的结果相差 0.36。

错误在哪里?在我的代码中还是在计算方法中?

【问题讨论】:

  • 你可以找到关于这个问题的详细解释stackoverflow.com/questions/11759992/…
  • 该问题的代码示例也给了我与我尝试过的所有在线计算器不同的结果,相差+-30或40,我的代码更接近在线计算器结果。
  • 检查我发布的答案,我能够修改你的代码以获得在线计算器的答案,并详细说明了我是如何得到它的

标签: javascript date time julian-date


【解决方案1】:

根据 StackOverflow 问题here,我修改了你的JsFiddle

我已根据

更改了您的实现

2440587.5 天 + UNIX TIME 天 === 儒略日

(UNIX TIME / 86400000) + 2440587.5) === 朱利安日;

并更新了您的代码以反映为var JD = time/86400000 + 2440587.5; 为了获得与在线计算器相同的结果,我不得不使用您在在线示例中使用的 UTC 时间。

【讨论】:

  • 谢谢,毕竟我的代码实现工作了,我不得不使用一些值作为整数而不是双精度值,比如这个 var JD = parseInt(B)+parseInt(C)+(D)+parseInt(E)+1720994.5;
  • 这没有回答问题“错误在哪里”。
  • @Mark——这是你的实际答案,你引用的页面有“A=INT(Y/100)”所以你应该做类似var A = Y / 100 | 0或使用Math.floor 或 parseInt 在使用 INT(…) 的地方截断小数部分。这同样适用于 BCE
【解决方案2】:

如果你只需要公历日期,你可以使用这个功能:

function jdFromDate(dateTime) {
    return (
        Date.UTC(
            dateTime.getFullYear(),
            dateTime.getMonth(),
            dateTime.getDate()
        ) /
            86400000 +
        2440588
    );
}

至于公历与儒略历的讨论,这比许多人想象的要复杂得多。一些国家很晚才采用公历(例如英国,除了 1752 年的苏格兰),因此比较 1582 年和 1918 年(俄罗斯采用公历)之间的历史日期是一项艰巨的任务,具体取决于您的用例。如果您只是想将日期存储为 JD 以使它们可在不同平台上使用(例如,简单地显示它们),那么不同日历的使用可能太多了。我与早期现代资源进行了广泛的合作,很难掌握哪个资源说明了哪个日历系统的日期(另请注意,1 月 1 日可能不是当时每个地区一年的第一天...... )。有关该主题的更多信息,您可能需要查看 Nachum Dershowitz 和 Edward Reingold 的“日历计算”——不过,它们不仅仅涵盖这两个日历系统 :-)

【讨论】:

    【解决方案3】:

    正如您在对 Lasitha Ishan Petthawadu 的回答的评论中所说的那样,您需要对 A、B、C 和 E 的值进行下限。在不使用库的情况下,算法 linked from the OP 的一个相当字面实现的版本是:

    function toJulianDate(date) {
      var floor = Math.floor;
      var y = date.getUTCFullYear();
      var m = date.getUTCMonth() + 1;
      var d = date.getUTCDate() + (date % 8.64e7) / 8.64e7;
      
      if (m < 3) {
        y -= 1;
        m += 12;
      }
      
      var a = floor(y/100);
      var b = date < new Date(Date.UTC(1582,9,15))? 0 : 2 - a + floor(a/4);
      var c = floor(y < 0? 365.25 * y - 0.75 : 365.25 * y);
      var e = floor(30.6001 * (m + 1));
      
      return b + c + d + e + 1720994.5;
    }
    
    console.log(toJulianDate(new Date('2018-04-07T23:45:16-03:00'))); // 2458216.6147685186
    
    console.log(toJulianDate(new Date('2018-04-08T02:45:16Z'))); // 2458216.6147685186

    创建日期时,我使用了严格的 ISO 8601 扩展格式。其他任何东西都不应使用内置解析器。

    【讨论】:

    • 根据我的实验,Javascript Date 函数似乎无法识别儒略历并将所有日期视为公历,即使是 1582 年 10 月 15 日之前的日期。ecma-international.org/ecma-262/5.1/#sec-15.9.1.15 声明“YYYY 是年份的十进制数字公历中的 0000 到 9999。”
    • @GerardAshton——我不明白你发表评论的原因。这是 OP 提供的算法的实现,用于从 ECMAScript 日期对象生成儒略日期字符串。没有声明或推断内置解析器理解儒略日期,恰恰相反。
    • 我还没有破译算法中的所有幻数。但我不明白为什么 RobG 的算法关心日期是在罗马采用公历的日期之前还是之后。
    • @GerardAshton——正如我一直说的,这不是我的算法,而是linked by the OP 的算法。对我来说,这似乎是 1 年零 1 天,但这可能只是因为 ECMAScript 有一个年份 0000,这通常不被认可。算法问题或 1582 年 10 月 15 日之前的日期应与 OP 或链接算法的作者讨论。
    猜你喜欢
    • 2015-09-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-09-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多