在WSO2平台中,我发现了一种有趣的行为,即使用Calendar来转换字符串到日期。WSO2使用java.util.Calendar作为最终结果。我发现,如果代码片段中使用的日期为01.01.1947 - 23.02.1947,则结果总是在前一天给出。我发现这是我们的时区,因为这是一个小时前。意思是日历向后减少一个小时的结果,然后在晚上11点前一天
到目前为止,我们已经解决了这个问题。所以这不是问题所在。
问题是,为什么这只发生在日期01.01.1947 - 23.02.1947?
下面是一个可以模拟问题的示例代码片段:
int year = 1947;
int month = 2;
int day = 23;
int timezoneOffset = TimeZone.getDefault().getRawOffset();
Calendar calendar = Calendar.getInstance();
calendar.clear();
calendar.set(1, year);
calendar.set(2, month - 1);
calendar.set(5, day);
calendar.set(15, timezoneOffset);
System.out.println(calendar.getTime());在我的时区中,timezoneOffset的结果是3600000,以防您想测试我的时区(捷克共和国)。
请注意,这是用WSO2编写的代码,如果有相关问题,我无法更改它。
我所使用的Java版本是: openjdk 11.0.8 2020-07-14
链接: WSO2平台
发布于 2021-03-24 08:00:33
发布于 2021-03-29 20:59:48
Federico klez Culloca的答复是正确的,在历史上也很有趣。
除此之外,我要指出的是,您使用的是几年前被JSR 310中定义的现代java.time类取代的糟糕的日期时间类。我们可以使用java.time查看在另一个答案中解释的偏移量的变化。

下面是对代码的重写,以避免这些遗留类。
首先,确定日期。
int year = 1947;
int month = 2;
int day = 23;
LocalDate localDate = LocalDate.of(year,month,day);接下来,选择几个白天的时间值。1 AM是在2 AM跳到3 AM之前,4 AM是在跳后。让我们看看这两个。
LocalTime beforeJump = LocalTime.of( 1 , 0 ) ;
LocalTime afterJump = LocalTime.of( 4 , 0 ) ;将时区定义为ZoneId。
ZoneId zoneId = ZoneId.of( "Europe/Prague" ) ;结合起来确定一个时刻,得到一个ZonedDateTime对象。
ZonedDateTime zdtBeforeJump = ZonedDateTime.of( localDate , beforeJump , z );
ZonedDateTime zdtAfterJump = ZonedDateTime.of( localDate , afterJump , z );跑步时:
zdtBeforeJump.toString() = 1947-02-23T01:00Z[Europe/Prague]
zdtAfterJump.toString() = 1947-02-23T04:00+01:00[Europe/Prague]我们可以在生成的文本中看到,从世界协调时的偏移从零小时-分钟-秒,如Z (祖鲁时间)所指示的,到一个偏移1小时比世界协调时。
我们可以用代码询问偏移量。从ZoneId对象中获取作为ZoneRules对象的区域规则。这提供了过去、现在和未来对这一特定地区人民使用的抵消的历史变化。
从我们的时区调整到偏移量为零,产生ZoneRules#getOffset所需的ZoneRules#getOffset对象。然后询问在那个区域的有效偏移量的规则。因此,我们得到一个ZoneOffset对象。
ZoneRules rules = z.getRules();
ZoneOffset offsetBeforeJump = rules.getOffset( zdtBeforeJump.toInstant() );
ZoneOffset offsetAfterJump = rules.getOffset( zdtAfterJump.toInstant() );跑的时候。
offsetBeforeJump.toString() = Z
offsetAfterJump.toString() = +01:00您可以同时看到所有的代码,在IdeOne.com现场运行。
➥的结果与生成的文本相同:跳转前为零偏移量,跳转后为+01:00。
关于java.time
https://docs.oracle.com/en/java/javase/11/docs/api/java.base/java/time/package-summary.html框架内置到Java8和更高版本中。这些类取代了麻烦的旧遗赠日期时间类,如java.util.Date、Calendar和SimpleDateFormat。
要了解更多信息,请参见http://docs.oracle.com/javase/tutorial/datetime/TOC.html。并搜索堆栈溢出以获得许多示例和解释。规范是JSR 310。
http://www.joda.org/joda-time/项目现在在维护模式中,建议迁移到java.time类。
您可以直接与数据库交换java.time对象。使用与JDBC 4.2或更高版本兼容的JDBC 4.2。不需要字符串,也不需要java.sql.*类。Hibernate 5&JPA2.2支持java.time。
在哪里获得java.time类?
https://stackoverflow.com/questions/66776697
复制相似问题