tl;dr
ZonedDateTime.parse(
"Friday, September 26, 2008 8:30 PM Eastern Daylight Time" ,
DateTimeFormatter.ofPattern( "EEEE, MMMM d, uuuu h:m a zzzz" )
).getZone()
java.time
现代的方式是使用java.time类。问题和其他答案使用麻烦的旧遗留日期时间类或Joda-Time项目,这两个项目现在都被java.time类所取代。
使用格式化模式定义一个DateTimeFormatter对象以匹配您的数据。
DateTimeFormatter f = DateTimeFormatter.ofPattern( "EEEE, MMMM d, uuuu h:m a zzzz" );
指定一个 Locale
来确定日期名称和月份名称所使用的人类语言,以及其他格式问题的文化规范。
f = f.withLocale( Locale.US );
最后,进行解析以获取一个
ZonedDateTime
对象。
String input = "Friday, September 26, 2008 8:30 PM Eastern Daylight Time" ;
ZonedDateTime zdt = ZonedDateTime.parse( input , f );
zdt.toString(): 2008-09-26T20:30-04:00[America/New_York]
您可以从表示为ZoneId
对象的ZonedDateTime
中请求时区。如果您需要有关时区的更多信息,可以查询ZoneId
。
ZoneId z = zdt.getZone();
在IdeOne.com上亲自查看。
ISO 8601
避免使用这种糟糕的日期时间格式进行交换。不要假设英语,不要用像星期几这样的东西来装饰你的输出,也永远不要使用伪时区,比如Eastern Daylight Time
。
对于时区:以continent/region
的格式指定正确的时区名称,例如{{link3:America/Montreal
}},{{link4:Africa/Casablanca
}}或Pacific/Auckland
。永远不要使用3-4个字母的缩写,比如EST
或IST
,因为它们不是真正的时区,没有标准化,甚至不是唯一的(!)。
将日期时间值序列化为文本时,请仅使用ISO 8601格式。当解析/生成字符串以表示其值时,java.time类默认使用这些格式。
关于java.time
java.time框架已经内置在Java 8及其之后的版本中。这些类替代了麻烦的遗留日期时间类,例如java.util.Date
、Calendar
和SimpleDateFormat
。
Joda-Time项目现在处于维护模式,建议迁移到java.time。
要了解更多,请参阅
Oracle教程。并在Stack Overflow上搜索许多示例和解释。规范是
JSR 310。
如何获取java.time类?
ThreeTen-Extra项目通过增加类扩展了java.time。该项目是java.time可能未来添加内容的试验场。您可能会在此处找到一些有用的类,例如Interval
, YearWeek
, YearQuarter
以及更多。
Date
和Calendar
类是一个混乱的烂摊子:设计不良、令人困惑和麻烦。避免使用它们,改用java.time类。 - Basil Bourque