正如Singh 正确接受的答案所说,您Date
实际上是在 UTC 中,但它的toString
方法在生成字符串时会混淆地应用当前默认时区。
ISO 8601
避免使用日期时间值等格式10/16/2012 12:06 PM
。序列化为文本时,请使用为此目的定义为标准的ISO 8601格式。
java.time
如果这似乎是一个简单的问题,我很抱歉我在 Java 日期方面遇到了很多麻烦
不是你;这是课程。旧的遗留日期时间类在处理日期时间方面是行业领先的英勇努力。但事实证明,它们构思不周、设计糟糕、非常混乱和麻烦。现在被 java.time 类所取代——一个巨大的改进。
完全避免这个麻烦的旧java.util.Date
课程。而是使用Instant
它的位置。
Instant
该类表示UTCInstant
时间线上的时刻,分辨率为纳秒(最多九 (9) 位小数)。
获取当前时刻。
Instant instant = Instant.now();
您可以通过调用添加到旧日期时间类的新转换方法之一将 Date 转换为其现代替换。只需调用toInstant,很简单。
Instant instant = myJavaUtilDate.toInstant();
java.time 类在生成字符串时默认使用 ISO 8601 格式。只需调用toString
即可获得对象内值的清晰表示。
String output = instant.toString();
2016-12-23T01:33:09.731Z
解析
要解析您的输入字符串,请定义要匹配的格式模式。模式代码与 的相似,SimpleDateFormat
但不完全相同。所以一定要仔细研究文档。
String input = "10/16/2012 12:06 PM" ;
DateTimeFormatter f = DateTimeFormatter.ofPattern( "MM/dd/uuuu hh:mm a" );
您的输入缺乏关于从 UTC 偏移或时区的任何线索。所以我们必须解析为LocalDateTime
. 缺少任何偏移或区域,aLocalDateTime
只是关于可能时刻的模糊概念,但并不代表时间线上的一个点。
LocalDateTime ldt = LocalDateTime.parse( input , f );
ldt.toString(): 2012-10-16T12:06
该问题声称这是针对“EST 时区”的。所以我们需要对我们应用一个时区 aZoneId
来LocalDateTime
获得 a ZonedDateTime
。
以、或等格式指定适当的时区名称。永远不要使用 3-4 个字母的缩写,例如或,因为它们不是真正的时区,不是标准化的,甚至不是唯一的(!)。continent/region
America/Montreal
Africa/Casablanca
Pacific/Auckland
EST
IST
也许EST
您指的是美国和加拿大东海岸大部分地区使用的时区。我会随意选择America/New_York
。
ZoneId z = ZoneId.of( "America/New_York" );
ZonedDateTime zdt = ldt.atZone( z );
zdt.toString(): 2012-10-16T12:06-04:00[美国/纽约]
要获得 UTC,只需提取一个Instant
. 您可以在概念上将其视为:
ZonedDateTime = ( Instant + ZoneId )
Instant instant = zdt.toInstant();
即时.toString(): 2012-10-16T16:06:00Z