我对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日?
答案 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.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 desugaring 和 How to use ThreeTenABP in Android Project。