将日期字符串(EST)转换为Java日期(UTC)

我需要一些关于这个java方法的建议。 此方法的目的是获取表示日期的字符串 – 此字符串是从EST时区中的日期创建的 – 并将其转换为UTC时区中的Java Date对象。

private Date buildValidationDate(String dateString) throws ParseException { System.out.println("dateString " + dateString); SimpleDateFormat dateFormat = new SimpleDateFormat("MM/dd/yyy hh:mm a"); dateFormat.setTimeZone(TimeZone.getTimeZone("UTC")); dateFormat.setLenient(true); Date dt = dateFormat.parse(dateString); System.out.println("dt " + dt); return dt; } 

我看到的问题是dt的价值似乎已经消失了。 例如,如果dateString是’10 / 16/2012 12:06 PM’ – 我期望dt(以UTC为单位)的值类似于’2012年10月16日星期二下午4:06’。 相反,dt的值是’Tue Oct 16 07:06:00 CDT 2012’。 这似乎不是正确的UTC时间。

我很感激任何建议,我很抱歉,如果这似乎是一个简单的问题,我在Java日期遇到了很多麻烦。 我不确定我是否编码错误或者我的方法有问题。 谢谢

您的日期正在转换正确 。 它的默认时区格式的打印值为java.util.Date与时区无关。 如果您需要特定于时区的处理,请使用java.util.Calendar

正如Singh所说的正确接受的答案所说,你的Date实际上 UTC,但是它的toString方法在生成字符串时会混淆地应用当前的默认时区。

ISO 8601

避免使用日期时间值为10/16/2012 12:06 PM格式。 序列化为文本时,请使用为此目的定义为标准的ISO 8601格式。

java.time

我很抱歉,如果这似乎是一个简单的问题,我在Java日期遇到了很多麻烦

不是你; 这是课程。 旧的遗留日期时间类是处理日期时间的英勇行业领导者。 但事实certificate他们构思错误,设计不合理,非常混乱,而且很麻烦。 现在取代了java.time类 – 一个巨大的改进。

完全避免使用这个麻烦的旧java.util.Date类。 而是使用Instant代替它。

Instant

Instant类表示UTC时间轴上的一个时刻,分辨率为纳秒 (最多九(9)位小数)。

获取当前时刻。

 Instant instant = Instant.now(); 

您可以通过调用添加到旧日期时间类的新转换方法之一将Date转换为其现代替换。 只需打电话给即时,很容易。

 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 。 缺少任何偏移或区域, LocalDateTime只是关于可能时刻的模糊概念,但不代表时间轴上的一个点。

 LocalDateTime ldt = LocalDateTime.parse( input , f ); 

ldt.toString():2012-10-16T12:06

该问题声称这是为了“EST时区”。 因此,我们需要将时区ZoneId应用于LocalDateTime以获取ZonedDateTime

continent/region的格式指定适当的时区名称 ,例如America/MontrealAfrica/CasablancaPacific/Auckland 。 切勿使用3-4字母缩写,例如ESTIST因为它们不是真正的时区,不是标准化的,甚至不是唯一的(!)。

也许在EST您的意思是在美国和加拿大东海岸的大部分地区使用的时区。 我会任意选择America/New_York

 ZoneId z = ZoneId.of( "America/New_York" ); ZonedDateTime zdt = ldt.atZone( z ); 

zdt.toString():2012-10-16T12:06-04:00 [America / New_York]

要获得UTC,只需提取一个Instant 。 您可以在概念上将其视为:

ZonedDateTime =(Instant + ZoneId)

 Instant instant = zdt.toInstant(); 

instant.toString():2012-10-16T16:06:00Z