Java 日历奇怪的行为

use*_*492 1 java calendar

我正在使用java中的日历对象将输入日期(年/月/日期等从网络获取)转换为纪元时间。我正在重用相同的日历对象。有时我从网络获取的年份是 0,并且没有对此进行过验证。一旦发生这种情况,每当我将日期转换为纪元时,我得到的纪元时间总是负数。这是有效的行为吗

请查找我在对此问题进行单元测试时得到的示例代码和结果。

    Calendar cal= Calendar.getInstance();        
    cal.set(Calendar.YEAR, 0); 
    System.out.println("time 1 : "+cal.getTimeInMillis());  
    System.out.println("Date 1 : "+new Date(cal.getTimeInMillis()));  

    cal.set(Calendar.YEAR, 2020); 
    System.out.println("time 2 : "+cal.getTimeInMillis());
    System.out.println("Date 2 : "+new Date(cal.getTimeInMillis()));  

    cal.set(Calendar.YEAR, 2010); 
    cal.set(Calendar.MONTH, 10);
    System.out.println("time 3 : "+cal.getTimeInMillis());
    System.out.println("Date 3 : "+new Date(cal.getTimeInMillis())); 
Run Code Online (Sandbox Code Playgroud)

此代码的输出为
时间 1:-62151385126938
日期 1:Sun Jul 04 11:51:13 IST 1

时间 2:-125866201126938
日期 2:7 月 4 日星期三 11:51:13 IST 2020

时间 3:-125540041126938
日期 3:11 月 4 日星期五 11:51:13 IST 2010

这是 java Calendar 的预期行为吗?

我的 JDK 版本是 OpenJDK 运行时环境 Corretto-8.252.09.1(内部版本 1.8.0_252-b09)

编辑:还有其他选项/类可以解决此问题,但我的目的是找到此行为的根本原因

Bas*_*que 5

\n

我正在使用日历对象

\n
\n

别那样做。永远不要使用可怕的Calendar和Date类。仅使用 JSR 310 中定义的现代java.time类。

\n
\n

有时我从网络获取的年份是 0,并且没有对此进行过验证。一旦发生这种情况,每当我将日期转换为纪元时,我得到的纪元时间总是负数。这是有效的行为吗

\n
\n

是的,对于 0 年的日期,自 UTC 1970 年第一个时刻的纪元参考以来的负毫秒数是正确的。0000 年发生在两千多年前,因此从 1970-01-01T00:00Z 倒算,这将是一个非常大的毫秒数。

\n

据我所知,Calendar在重置当代年份后,您会看到返回奇怪的负数。如果您想了解更多信息,请参阅Ole VV 的出色回答Calendar在我看来:既然我们有了java.time ,就没有必要进行调查了。让\xe2\x80\x99s埋葬死者,然后继续前进。

\n

如果您必须与尚未更新java.time的旧代码进行互操作,您可以在遗留类和现代类之间来回转换。查看添加到旧类中的新方法。尽量减少对旧遗留类的使用。

\n
if( myCalendar instanceof GregorianCalendar ) \n{\n    ZonedDateTime zdt = ( ( GregorianCalendar ) myCalendar ).toZonedDateTime() ;\n}\n
Run Code Online (Sandbox Code Playgroud)\n

\xe2\x80\xa6 和 \xe2\x80\xa6

\n
Calendar myCalendar = GregorianCalendar.from( zdt ) ;\n
Run Code Online (Sandbox Code Playgroud)\n

你说:

\n
\n

我正在重用相同的日历对象。

\n
\n

别那样做。重用该类的对象会导致各种问题。

\n

java.time中重要的设计考虑因素之一是仅使用不可变对象,以避免这些重用问题。

\n
\n

我使用java中的日历对象来转换输入日期(年/月/日

\n
\n

您没有向我们展示此代码,因此我无法进一步帮助您。

\n

发布前搜索 Stack Overflow。所有这些已经被讨论过很多次了。

\n