【问题标题】:Convert date string (EST) to Java Date (UTC)将日期字符串 (EST) 转换为 Java 日期 (UTC)
【发布时间】:2012-10-16 16:16:22
【问题描述】:

我需要一些关于这个 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 为单位)类似于 'Tuesday, October 16, 2012 4:06 PM'。相反,dt 的值是 'Tue Oct 16 07:06:00 CDT 2012'。这似乎不是正确的 UTC 时间。

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

【问题讨论】:

    标签: java date simpledateformat data-conversion


    【解决方案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();
    

    您可以通过调用添加到旧日期时间类的新转换方法之一,将日期转换为其现代替换。只需调用 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。缺少任何偏移或区域,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。切勿使用 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[美国/纽约]

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

    ZonedDateTime = ( Instant + ZoneId )

    Instant instant = zdt.toInstant();
    

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

    【讨论】:

      【解决方案2】:

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

      【讨论】:

      猜你喜欢
      • 2021-04-19
      • 2012-07-02
      • 2020-03-21
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-02-28
      • 1970-01-01
      • 2014-01-24
      相关资源
      最近更新 更多