栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 面试经验 > 面试问答

如何从ISO 8601格式的字符串中选择时区到Calendar instace

面试问答 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

如何从ISO 8601格式的字符串中选择时区到Calendar instace

创建时

Calendar
,它将采用JVM的默认时区。而且,当您
String
将a
解析为a时
Date
,它只会设置一个值:自历元(
1970-01-01T00:00Z
)以来的毫秒数。A
Date

没有任何时区信息,仅此毫秒值。因此,您需要在日历中设置时区。

在格式化程序中,您将其

Z
视为文字,因为它位于引号(
'Z'
)内。这将忽略偏移量,并获取JVM默认时区中的日期(如果对应的偏移量不是-08:00,则它将具有不同的值)。

在JDK> = 7中,可以使用该

X
模式来解析偏移量:

Date date = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ssX", Locale.US).parse(iso8601Date);

但这不会在日历中设置时区(它仍将使用JVM的默认值)。因此,“更好”的方法是从输入中去除偏移量并分别处理它:

Calendar calendar = GregorianCalendar.getInstance();String iso8601Date = "2017-04-04T09:00:00-08:00";// get the offset (-08:00)String offset = iso8601Date.substring(19);TimeZone tz = TimeZone.getTimeZone("GMT" + offset);SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss", Locale.US);// set the offset in the formattersdf.setTimeZone(tz);// parse just date and time (without the offset)Date date = sdf.parse(iso8601Date.substring(0, 19));// set the offset in the calendarcalendar.setTimeZone(tz);calendar.setTime(date);

这样,日历将

-08:00
设置偏移量。正如@BasilBourque的回答已经说的那样,它
-08:00
是一个偏移量,而不是时区(
TimeZone
该类将偏移量视为时区一样对待偏移量,这是一种解决方法/错误的设计选择)。


Java新的日期/时间API

老班(

Date
Calendar
SimpleDateFormat
)有很多问题和设计问题,他们正在被新的API取代。

在Android中,您可以使用ThreeTen Backport,这是Java
8的新日期/时间类的绝佳反向端口。您还需要ThreeTenABP使其起作用(更多有关如何在此处使用的信息)。

@BasilBourque的答案已经告诉您有关的信息

OffsetDateTime
。但是要转换为a
Calendar
,您可以使用a
org.threeten.bp.ZonedDateTime
并使用以下
org.threeten.bp.DateTimeUtils
类将其转换:

String iso8601Date = "2017-04-04T09:00:00-08:00";ZonedDateTime zdt = ZonedDateTime.parse(iso8601Date);Calendar cal = DateTimeUtils.toGregorianCalendar(zdt);

日历将已经设置了

-08:00
偏移量。


如果要从偏移量获取时区,恐怕不是那么简单。多个时区可以使用相同的offset,因此您无法确定要使用哪个时区(最好的方法是获取可能的候选者列表)。


java.util.Date

只是有关的更详细的说明

java.util.Date
。该链接对此有很多解释,所以我真的建议您阅读它。

如上所述,a

Date
没有时区信息。它只是让纪元以来的毫秒数(是
1970-01-01T00:00Z
年1月1 日
1970年,在午夜UTC
)。

这个值在世界各地都一样。示例:目前,我正在编写此代码,当前时间的Millis值为

1504632865935
。对于世界上任何人,无论我使用的是哪个时区,在与我相同的时间获取当前时间的人,此数字都是相同的。

与该毫秒值相对应的 当地日期和时间 有所不同。在UTC,它对应于

2017-09-05T17:34:25.935Z
在纽约,日期是相同的(9月5 日
2017年),但时间是不同的(13:34),并在东京为九月 6 日 2017年在上午2时34分。

尽管

Date
对象是相同的(因为对象的Millis值适用
1504632865935
于每个人),但是 相应的 日期和时间会根据使用的时区而变化。

人们倾向于认为a

Date
具有时区,因为在打印时(通过
System.out.println
或通过日志记录)或在调试器中进行检查时,它隐式使用该
toString()
方法,并将日期转换为JVM的默认时区(并且还会打印时区名称)
)。这样给人的印象是,a
Date
设置了格式和时区,但没有。



转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/515957.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号