tl;博士
ZonedDateTime zdt = LocalDateTime.parse( input , DateTimeFormatter.forPattern( "dd/MM/uuuu hh:mm:ss" ) ).atZone( ZoneId.of( "America/Denver" ) );
避免使用旧的日期时间类
您正在使用旧的过时麻烦的遗留日期时间类。
java.time
java.time 框架内置于 Java 8 及更高版本中。这些类取代了旧的麻烦的日期时间类,例如java.util.Date、.Calendar 和java.text.SimpleDateFormat。
现在在maintenance mode,Joda-Time 项目也建议迁移到 java.time。
要了解更多信息,请参阅Oracle Tutorial。并在 Stack Overflow 上搜索许多示例和解释。
大部分 java.time 功能在ThreeTen-Backport 中向后移植到 Java 6 和 7,并在 ThreeTenABP 中进一步适应 Android。
ThreeTen-Extra 项目通过附加类扩展了 java.time。该项目是未来可能添加到 java.time 的试验场。
LocalDateTime
您的输入字符串缺少offset-from-UTC 或time zone 的任何指示。所以我们必须解析为LocalDateTime。 LocalDateTime 没有偏移或时区,所以它确实不代表时间轴上的时刻。就像说“圣诞节从 12 月 25 日午夜开始”一样,只有当您将其应用于地球上某个特定时区时,它才有意义(仅成为时间线上的一个点)。
String input = …
DateTimeFormatter f = DateTimeFormatter.forPattern( "dd/MM/uuuu hh:mm:ss" );
LocalDateTime ldt = LocalDateTime.parse( input , f );
ZonedDateTime
如果您知道上下文并且可以假设预期的偏移量或时区,您可以分别创建一个OffsetDateTime 或ZonedDateTime。
使用proper time zone names,命名格式为continent/region。 MST 可能是指美国落基山脉大部分地区使用的America/Denver 时区,或者加拿大部分地区使用的America/Edmonton。
切勿使用 3-4 个字母的缩写,例如 MST。这些缩写不是真正的时区,没有标准化,甚至不是唯一的(!)。
ZoneId zoneId = ZoneId.of( "America/Denver" ) ;
ZonedDateTime zdt = ldt.atZone( zoneId ) ;
转换
我建议避免使用臭名昭著的麻烦 java.util.Date 类。但如果你必须这样做,你可以convert to/from java.time types。要与其他代码或库互操作,请使用添加到旧类的新方法进行转换。在这种情况下,使用从OffsetDateTime 或ZonedDatetime 中提取的Instant 对象并传递给java.util.Date.from。
Instant 类代表 UTC 时间线上的时刻,分辨率为 nanoseconds。
java.util.Date utilDate = java.util.Date.from( zdt.toInstant() ) ;
换个方向,使用添加到旧类的另一个新方法,java.util.Instant::toInstant。
Instant instant = utilDate.toInstant();
ZonedDateTime zdt = instant.atZone( zoneId ) ;