带有详细时区的Java DateTimeFormatterBuilder
内容导读
互联网集市收集整理的这篇技术教程文章主要介绍了带有详细时区的Java DateTimeFormatterBuilder,小编现在分享给大家,供广大互联网技能从业者学习和参考。文章包含5001字,纯文字阅读大概需要8分钟。
内容图文
![带有详细时区的Java DateTimeFormatterBuilder](/upload/InfoBanner/zyjiaocheng/820/11999992f49345ad8a3249dca706b10c.jpg)
假设我有一个日期,例如:
Nov 30, 2013 19:00:00.001930000 Eastern Standard Time
我正在尝试使用DateTimeFormatterBuilder解析输入,但是我无法弄清楚要为通用类型ZoneId设置的内容如下所示.
String basePattern = "MMM dd, yyyy HH:mm:ss";
new DateTimeFormatterBuilder()
.appendPattern(basePattern)
.appendFraction(ChronoField.NANO_OF_SECOND,0,9, true)
.appendZoneText(TextStyle.FULL, null)
.toFormatter();
解决方法:
伪区
正如class documentation简要解释的那样,主流媒体中常见的3-4个字母表示时区并不是官方时区.这些伪区域不是标准化的,甚至不是唯一的!许多代码在全球范围内重复使用.例如,IST是印度标准时间和爱尔兰标准时间. CST既是中国标准时间也是Central Standard Time(北美).
切勿使用这些伪区域.以continent / region格式指定proper time zone name,例如America/Montreal,Africa/Casablanca或Pacific / Auckland.
解决歧义
如果您的输入确实具有这些伪区域,则采用缩写格式,您必须处理歧义.默认情况下,格式化程序构建器将尝试通过考虑格式化程序的区域设置来解决歧义.对于CST,如果Locale是Locale.CHINA,那么CST可能意味着中国标准时间而不是中央标准时间.
不幸的是,这是一种粗暴的做法区域设置和时区的问题是正交的.您可以让一个讲中文的用户处理芝加哥的交货数据,在这种情况下,Locale可能是中国,但数据中的CST表示Central Standard Time.因此,在这种情况下,您可以指定一个或多个时区,例如America/Chicago和America/Winnipeg在尝试解析CST以覆盖考虑Locale的默认值时由格式化程序考虑.
Set< ZoneID > zones = new TreeSet<>() ;
zones.add( ZoneId.of( "America/Chicago" ) ;
zones.add( ZoneId.of( "America/Manitoba" ) ;
…
.appendZoneText( TextStyle.SHORT , zones )
…
这是一个完整的示例,将我的macOS MacBook上的CST解析为中央标准时间设置为America / Los_Angeles的默认时区和Locale.US的默认语言环境.请注意,我们只将一个参数传递给appendZoneText(没有Set传递).
String input = "Nov 30, 2013 19:00:00.001930000 CST";
String basePattern = "MMM dd, yyyy HH:mm:ss";
DateTimeFormatter f = new DateTimeFormatterBuilder( )
.appendPattern( basePattern )
.appendFraction( ChronoField.NANO_OF_SECOND , 0 , 9 , true )
.appendPattern( " " )
.appendZoneText( TextStyle.SHORT )
.toFormatter( );
ZonedDateTime zdt = ZonedDateTime.parse( input , f );
System.out.println( "input: " + input );
System.out.println( "zdt.toString(): " + zdt );
input: Nov 30, 2013 19:00:00.001930000 CST
zdt.toString(): 2013-11-30T19:00:00.001930-06:00[America/Chicago]
让我们通过SetId对象来覆盖该行为,暗示CST意味着中国标准时间.这里我们传递一组ZoneId对象.我们使用相同的输入来获得非常不同的输出.
Set < ZoneId > zones = new HashSet <>( );
zones.add( ZoneId.of( "Asia/Shanghai" ) ) ;
String input = "Nov 30, 2013 19:00:00.001930000 CST";
String basePattern = "MMM dd, yyyy HH:mm:ss";
DateTimeFormatter f = new DateTimeFormatterBuilder( )
.appendPattern( basePattern )
.appendFraction( ChronoField.NANO_OF_SECOND , 0 , 9 , true )
.appendPattern( " " )
.appendZoneText( TextStyle.SHORT , zones )
.toFormatter( );
ZonedDateTime zdt = ZonedDateTime.parse( input , f );
System.out.println( "input: " + input );
System.out.println( "zdt.toString(): " + zdt );
input: Nov 30, 2013 19:00:00.001930000 CST
zdt.toString(): 2013-11-30T19:00:00.001930+08:00[Asia/Shanghai]
现在,在您的情况下,您具有伪区域的全名而不是缩写.所以可能没有歧义.所以你可能会逃脱overloaded method not taking a second argument.
.appendZoneText( TextStyle.FULL )
例:
String input = "Nov 30, 2013 19:00:00.001930000 Eastern Standard Time";
String basePattern = "MMM dd, yyyy HH:mm:ss";
DateTimeFormatter f = new DateTimeFormatterBuilder( )
.appendPattern( basePattern )
.appendFraction( ChronoField.NANO_OF_SECOND , 0 , 9 , true )
.appendPattern( " " )
.appendZoneText( TextStyle.FULL )
.toFormatter( );
ZonedDateTime zdt = ZonedDateTime.parse( input , f );
System.out.println( "input: " + input );
System.out.println( "zdt.toString(): " + zdt );
input: Nov 30, 2013 19:00:00.001930000 Eastern Standard Time
zdt.toString(): 2013-11-30T19:00:00.001930-05:00[America/New_York]
然而,在这里传递一组ZoneId对象也很有用. Set用于将时区分配给实例化的ZonedDateTime对象.请注意上面的输出中默认分配了America / New_York.但是还有许多其他时区也被伪区“东部标准时间”所暗示,例如巴哈马,美国/拿骚和墨西哥的坎昆,等等.
然而,选择应用集合中的哪个元素对我来说是一个谜.我尝试使用SortedSet思考可以选择在Set的自然顺序中找到的第一个.唉,ZoneId没有实现Comparable接口,因此无法使用诸如TreeSet之类的SortedSet.
Set < ZoneId > zones = new HashSet <>( );
zones.add( ZoneId.of( "America/Detroit" ) );
zones.add( ZoneId.of( "America/New_York" ) );
zones.add( ZoneId.of( "America/Nassau" ) );
zones.add( ZoneId.of( "America/Cancun" ) );
String input = "Nov 30, 2013 19:00:00.001930000 Eastern Standard Time";
String basePattern = "MMM dd, yyyy HH:mm:ss";
DateTimeFormatter f = new DateTimeFormatterBuilder( )
.appendPattern( basePattern )
.appendFraction( ChronoField.NANO_OF_SECOND , 0 , 9 , true )
.appendPattern( " " )
.appendZoneText( TextStyle.FULL , zones )
.toFormatter( );
ZonedDateTime zdt = ZonedDateTime.parse( input , f );
System.out.println( "input: " + input );
System.out.println( "zdt.toString(): " + zdt );
input: Nov 30, 2013 19:00:00.001930000 Eastern Standard Time
zdt.toString(): 2013-11-30T19:00:00.001930-06:00[America/Cancun]
内容总结
以上是互联网集市为您收集整理的带有详细时区的Java DateTimeFormatterBuilder全部内容,希望文章能够帮你解决带有详细时区的Java DateTimeFormatterBuilder所遇到的程序开发问题。 如果觉得互联网集市技术教程内容还不错,欢迎将互联网集市网站推荐给程序员好友。
内容备注
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 gblab@vip.qq.com 举报,一经查实,本站将立刻删除。
内容手机端
扫描二维码推送至手机访问。