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

时间:2012-10-16 16:16:22

标签: java date simpledateformat data-conversion

我需要一些关于这个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日期遇到了很多麻烦。我不确定我的编码是不正确的,还是我的方法有问题。感谢

2 个答案:

答案 0 :(得分:3)

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

答案 1 :(得分:1)

正如correct accepted answer by Singh所说,Date实际上 是UTC的,但toString方法在生成字符串时会混淆地应用当前的默认时区。

ISO 8601

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

java.time

  

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

不是你;这是班级。旧的遗留日期时间类是处理日期时间的勇敢行业领先的努力。但事实证明他们构思错误,设计不合理,非常混乱,而且很麻烦。现在取代了java.time类 - 一个巨大的改进。

完全避免这个麻烦的旧java.util.Date课程。而是在其位置使用Instant

Instant

Instant类代表UTC中时间轴上的一个时刻,分辨率为nanoseconds(小数部分最多九(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的格式指定proper time zone name,例如America/MontrealAfrica/CasablancaPacific/Auckland。切勿使用诸如ESTIST之类的3-4字母缩写,因为它们不是真正的时区,不是标准化的,甚至不是唯一的(!)。

也许是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

相关问题