Java 为什么在格式化日期时有些日期显示为BST,有些日期显示为GMT?
我有以下两个输入字符串:Java 为什么在格式化日期时有些日期显示为BST,有些日期显示为GMT?,java,date,parsing,timezone,simpledateformat,Java,Date,Parsing,Timezone,Simpledateformat,我有以下两个输入字符串: String string1 = "2017-01-30T13:00:00+0000" String string2 = "2018-06-23T16:00:00+0000" 对于string1,当我这样做时,我会得到以下信息: SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ssZ"); Date startDate = formatter.parse(string1);
String string1 = "2017-01-30T13:00:00+0000"
String string2 = "2018-06-23T16:00:00+0000"
对于string1,当我这样做时,我会得到以下信息:
SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ssZ");
Date startDate = formatter.parse(string1);
结果-2017年1月30日星期一13:00:00 GMT
但是,当我对string2执行相同操作时,我在调试器中会得到以下结果:
Sat Jun 23 17:00:00 BST 2018
为什么我在这里有不同的时区 tl;博士
java.time
您正在使用的麻烦的旧遗留类的许多设计缺陷之一是,Date::toString
方法在生成字符串时应用JVM的当前默认时区。因此,虽然内部的值实际上是UTC,但令人困惑的是,它似乎有另一个时区。此外,您当前的默认时区在两个日期之间会经历夏时制转换
而是使用现代的java.time类。将输入字符串解析为对象
OffsetDateTime odt = OffsetDateTime.parse( "2017-01-30T13:00:00+0000" ) ;
Java8和Java9中的一个bug可能会在解析与UTC之间的偏移量时产生影响,在小时和分钟之间缺少冒号。作为解决方法,添加冒号
OffsetDateTime odt = OffsetDateTime.parse( "2017-01-30T13:00:00+0000".replace( "+0000" , "+00:00" ) ;
调用toString
以生成标准ISO 8601格式的字符串。与日期
不同,动态应用的任何时区都不会掺杂结果
如果需要,分配一个ZoneId
以获取zoneDateTime
以大陆/地区
的格式指定,例如,或太平洋/奥克兰
。切勿使用3-4个字母的缩写,例如BST
或EST
或IST
,因为它们不是真正的时区,不标准化,甚至不是唯一的(!)
看
转储到控制台
System.out.println( "input2017: " + input2017 ) ;
System.out.println( "odt2017: " + odt2017 ) ;
System.out.println( "zdt2017: " + zdt2017 ) ;
System.out.println( "" ) ; // Blank line.
System.out.println( "input2018: " + input2018 ) ;
System.out.println( "odt2018: " + odt2018 ) ;
System.out.println( "zdt2018: " + zdt2018 ) ;
请注意,在2018年6月,欧洲/伦敦的时间是如何向前跳了一个小时的。在冬季,伦敦地区是UTC,但在夏季,比UTC提前一小时
2017
输入2017:2017-01-30T13:00:00+00:00
odt2017:2017-01-30T13:00Z
zdt2017:2017-01-30T13:00Z[欧洲/伦敦]
2018
输入2018:2018-06-23T16:00:00+00:00
odt2018:2018-06-23T16:00Z
zdt2018:2018-06-23T17:00+01:00[欧洲/伦敦]
搜索堆栈溢出以获取更多信息,因为此主题已被处理多次
关于java.time 该框架内置于Java8及更高版本中。这些类取代了麻烦的旧日期时间类,例如,& 该项目现已启动,建议迁移到类 要了解更多信息,请参阅。并搜索堆栈溢出以获得许多示例和解释。规格是 您可以直接与数据库交换java.time对象。使用兼容的或更高版本。不需要字符串,也不需要
java.sql.*
类
从哪里获得java.time类
- ,及以后
- 内置的李>
- 标准JavaAPI的一部分,带有捆绑实现
- Java9添加了一些次要功能和修复
- 及
- 大部分java.time功能都在中向后移植到Java6和Java7
-
- 更高版本的Android捆绑包实现了java.time类
- 对于早期的Android,该项目采用了ThreeTen Backport(如上所述)。看
Date::toString
方法在生成字符串时应用JVM的当前默认时区。因此,虽然内部的值实际上是UTC,但令人困惑的是,它似乎有另一个时区。此外,您当前的默认时区在两个日期之间会经历夏时制转换
而是使用现代的java.time类。将输入字符串解析为对象
OffsetDateTime odt = OffsetDateTime.parse( "2017-01-30T13:00:00+0000" ) ;
Java8和Java9中的一个bug可能会在解析与UTC之间的偏移量时产生影响,在小时和分钟之间缺少冒号。作为解决方法,添加冒号
OffsetDateTime odt = OffsetDateTime.parse( "2017-01-30T13:00:00+0000".replace( "+0000" , "+00:00" ) ;
调用toString
以生成标准ISO 8601格式的字符串。与日期
不同,动态应用的任何时区都不会掺杂结果
如果需要,分配一个ZoneId
以获取zoneDateTime
以大陆/地区
的格式指定,例如,或太平洋/奥克兰
。切勿使用3-4个字母的缩写,例如BST
或EST
或IST
,因为它们不是真正的时区,不标准化,甚至不是唯一的(!)
看
转储到控制台
System.out.println( "input2017: " + input2017 ) ;
System.out.println( "odt2017: " + odt2017 ) ;
System.out.println( "zdt2017: " + zdt2017 ) ;
System.out.println( "" ) ; // Blank line.
System.out.println( "input2018: " + input2018 ) ;
System.out.println( "odt2018: " + odt2018 ) ;
System.out.println( "zdt2018: " + zdt2018 ) ;
请注意,在2018年6月,欧洲/伦敦的时间是如何向前跳了一个小时的。在冬季,伦敦地区是UTC,但在夏季,比UTC提前一小时
2017
输入2017:2017-01-30T13:00:00+00:00
odt2017:2017-01-30T13:00Z
zdt2017:2017-01-30T13:00Z[欧洲/伦敦]
2018
输入2018:2018-06-23T16:00:00+00:00
odt2018:2018-06-23T16:00Z
zdt2018:2018-06-23T17:00+01:00[欧洲/伦敦]
搜索堆栈溢出以获取更多信息,因为此主题已被处理多次
关于java.time 该框架内置于Java8及更高版本中。这些类取代了麻烦的旧日期时间类,例如,& 该项目现已启动,建议迁移到类 要了解更多信息,请参阅。并搜索堆栈溢出以获得许多示例和解释。规格是 您可以直接与数据库交换java.time对象。使用兼容的或更高版本。不需要字符串,也不需要
java.sql.*
类
从哪里获得java.time类
- ,及以后
- 内置的李>
- 标准JavaAPI的一部分,带有捆绑实现
- Java9添加了一些次要功能和修复
- 及