Java LocalDate格式化2000-1-2错误

Java LocalDate格式化2000-1-2错误,java,datetime-format,localdate,Java,Datetime Format,Localdate,今天,在一台新的构建机器上的一些测试失败了,而在其他机器上则是ok。考虑到这个问题,它表明 @Test public void testDateTimeFormater() { String result = LocalDate.of(2000,1,2) .format(DateTimeFormatter.ofPattern("YYYY-MM-dd")); Assert.assertTrue(result,result.equals("2000-01-02

今天,在一台新的构建机器上的一些测试失败了,而在其他机器上则是ok。考虑到这个问题,它表明

@Test
public void testDateTimeFormater()
{
    String result = LocalDate.of(2000,1,2)
            .format(DateTimeFormatter.ofPattern("YYYY-MM-dd"));
    Assert.assertTrue(result,result.equals("2000-01-02"));
}
结果为“java.lang.AssertionError:1999-01-02”

jave版本不工作

root@build02:~# java -version 
java version "1.8.0_181"
Java(TM) SE Runtime Environment (build 1.8.0_181-b13)
Java HotSpot(TM) 64-Bit Server VM (build 25.181-b13, mixed mode)
(操作系统Debian9,Ubuntu 18.04)

在开发人员机器上,工作的java版本是

java version "1.8.0_121"
Java(TM) SE Runtime Environment (build 1.8.0_121-b13)
Java HotSpot(TM) 64-Bit Server VM (build 25.121-b13, mixed mode)
(操作系统Ubuntu 14.04)


有什么问题吗?有什么我可以检查的吗?

您可能不想要“YYYY-MM-dd”格式,而是“yyy-MM-dd”

“Y”是以周为基础的年份,这取决于区域设置。在某些地区,2000年1月2日可能属于以周为基础的1999年,而在某些其他地区,则可能属于以周为基础的2000年


“y”是纪年,通常用作日历年。

您可能不希望使用“YYYY-MM-dd”格式,而希望使用“YYYY-MM-dd”格式

“Y”是以周为基础的年份,这取决于区域设置。在某些地区,2000年1月2日可能属于以周为基础的1999年,而在某些其他地区,则可能属于以周为基础的2000年


“y”是纪年,通常用作日历年。

当我刚刚打印结果的
toString()
方法时,很明显传递给
DateTimeFormatter
的格式是问题:

public static void main(String[] args) {
    String result = LocalDate.of(2000,1,2)
            .format(DateTimeFormatter.ofPattern("yyyy-MM-dd"));
    System.out.println(result.toString());

    String wrongResult = LocalDate.of(2000,1,2)
            .format(DateTimeFormatter.ofPattern("YYYY-MM-dd"));
    System.out.println(wrongResult.toString());
}
这张照片

2000-01-02
1999-01-02

因此,可能较旧的Java版本没有认识到这一差异,但较新的版本却认识到了这一差异。关于解释,请看@ThomasKläger的答案。

当我刚刚打印结果的
toString()
方法时,很明显传递给
DateTimeFormatter
的格式就是问题所在:

public static void main(String[] args) {
    String result = LocalDate.of(2000,1,2)
            .format(DateTimeFormatter.ofPattern("yyyy-MM-dd"));
    System.out.println(result.toString());

    String wrongResult = LocalDate.of(2000,1,2)
            .format(DateTimeFormatter.ofPattern("YYYY-MM-dd"));
    System.out.println(wrongResult.toString());
}
这张照片

2000-01-02
1999-01-02

因此,可能较旧的Java版本没有认识到这一差异,但较新的版本却认识到了这一差异。关于解释,请看@ThomasKläger的答案。

您最好
Assert.assertEquals(“2000-01-02”,result)
以获取更多信息性故障信息。您是否尝试过
“yyyy-MM-dd”
格式?也许大写字母“Y”就是问题所在。。。我试着打印它,但没有大写字母
“Y”
它可以工作。yyyy可以工作,但问题是为什么“yyy”可以在旧版本中工作?对于想要的结果,您不需要格式化程序。只需使用
LocalDate.of(2000,1,2).toString()
。除了错误的情况(
Y
而不是
Y
)之外,还有一个地区差异在捉弄你。出现错误的JVM有一个使用ISO 8601的默认区域设置。在ISO 8601中,2000年1月1日星期日属于1999年的最后一周,因此您得到了1999年。JVM似乎在工作,它使用US(或类似的)locale和week方案。在美国,这一天属于新年(我甚至认为它属于2000年的第二周)。对于其他日期,只要您使用
yyy
,您也会在这台计算机上得到不正确的结果。您最好
Assert.assertEquals(“2000-01-02”,结果)
以获取更多信息性故障信息。您是否尝试过
“yyyy-MM-dd”
格式?也许大写字母“Y”就是问题所在。。。我试着打印它,但没有大写字母
“Y”
它可以工作。yyyy可以工作,但问题是为什么“yyy”可以在旧版本中工作?对于想要的结果,您不需要格式化程序。只需使用
LocalDate.of(2000,1,2).toString()
。除了错误的情况(
Y
而不是
Y
)之外,还有一个地区差异在捉弄你。出现错误的JVM有一个使用ISO 8601的默认区域设置。在ISO 8601中,2000年1月1日星期日属于1999年的最后一周,因此您得到了1999年。JVM似乎在工作,它使用US(或类似的)locale和week方案。在美国,这一天属于新年(我甚至认为它属于2000年的第二周)。对于其他日期,只要您使用
YYYY
,您将在此计算机上获得不正确的结果。