Java和Javascript之间的区别在1月1日0001 UTC

时间:2014-06-02 13:55:28

标签: java javascript date utc

我对Java和Javascript中的日期1月1日UTC的表示方式有所不同

在Java中:

TimeZone utcTimeZone = TimeZone.getTimeZone("UTC");
Calendar cal = Calendar.getInstance(utcTimeZone);
cal.clear();
//1st Jan 0001
cal.set(1, 0, 1);
Date date = cal.getTime();
System.out.println(date);//Sat Jan 01 00:00:00 GMT 1
System.out.println(date.getTime());// -62135769600000

在JavaScript中:

var date = new Date();
date.setTime(-62135769600000);
date.toUTCString(); //"Sat, 30 Dec 0 00:00:00 GMT"

为什么日期,1月1日0001 UTC,由Java中的时间-62135769600000L表示,在Javascript中显示时不表示为1月1日?

2 个答案:

答案 0 :(得分:10)

看起来这是因为Java中的GregorianCalendar实际上是格里高利历和儒略历之间的混合:

  

GregorianCalendar是一个混合日历,支持Julian和Gregorian日历系统,并支持单个不连续性,默认情况下对应公历日期时的格里高利日期(1582年10月15日,某些国家/地区,其他)。调用者可以通过调用setGregorianChange()来更改切换日期。

例如,如果以1500-01-01为例,Java和Javascript值将相隔10天。

要使其成为纯GregorianCalendar,您可以使用:

GregorianCalendar cal = new GregorianCalendar(TimeZone.getTimeZone("UTC"));
cal.setGregorianChange(new Date(Long.MIN_VALUE));

然后你得到0001-01-01的值为-62135596800000,它给出了Javascript的相同日期。

转换日历是一种痛苦的问题 - 它们使各种事物变得奇怪,几乎从来没用过。 (我怀疑 适当的用例也可能有不同的要求。我最终决定不为Noda Time实现它。)

答案 1 :(得分:1)

java.time

java.util 日期时间 API 及其格式化 API SimpleDateFormat 已过时且容易出错。建议完全停止使用它们并切换到 modern Date-Time API*

使用 java.time(现代日期时间 API)的解决方案:

import java.time.OffsetDateTime;
import java.time.ZoneOffset;

public class Main {
    public static void main(String[] args) {
        System.out.println(OffsetDateTime.of(1, 1, 1, 0, 0, 0, 0, ZoneOffset.UTC).toInstant().toEpochMilli());
    }
}

输出:

-62135596800000

在线演示

Trail: Date Time 了解有关现代 Date-Time API 的更多信息。

JavaScript:

const date = new Date();
date.setTime(-62135596800000);
console.log(date.toUTCString()); // Mon, 01 Jan 0001 00:00:00 GMT


* 出于任何原因,如果您必须坚持使用 Java 6 或 Java 7,您可以使用 ThreeTen-Backport,它将大部分 java.time 功能向后移植到 Java 6 & 7. 如果您正在为 Android 项目工作并且您的 Android API 级别仍然不符合 Java-8,请检查 Java 8+ APIs available through desugaringHow to use ThreeTenABP in Android Project