【问题标题】:Date TimeZone conversion in java?java中的日期时区转换?
【发布时间】:2017-08-29 18:06:57
【问题描述】:

我一直在寻找将时间从 GMT 转换为本地时间的最简单方法。当然,要考虑正确的 DST 日期并尽可能标准。

我能想到的最直接的代码是:

SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
String inpt = "2011-23-03 16:40:44";
Date inptdate = null;
try {
    inptdate = sdf.parse(inpt);
} catch (ParseException e) {e.printStackTrace();}   
Calendar tgmt = new GregorianCalendar(TimeZone.getTimeZone("GMT"));
tgmt.setTime(inptdate);

Calendar tmad = new GregorianCalendar(TimeZone.getTimeZone("Europe/Madrid"));
tmad.setTime(inptdate);

System.out.println("GMT:\t\t" + sdf.format(tgmt.getTime()));
System.out.println("Europe/Madrid:\t" + sdf.format(tmad.getTime()));

但我认为我没有正确理解 getTime 将返回的内容。

【问题讨论】:

  • 你如何让TimeZone.getTimeZone("Europe/Madrid") 工作?我收到错误The method getTimeZone(String) is undefined for the type TimeZone
  • 没什么花哨的...这是一个 sn-p 实际工作代码:pastebin.com/5u79mBMW 每天在 Java 1.5 上运行几次。
  • 抱歉,写这篇文章后我发现我使用的是 GWT 版本的 TimeZone,并且它不允许字符串作为参数!
  • Timezone conversion的可能重复
  • 所以你的日期是 2011 年第 23 个月的第 3 天??你打算2011-03-23 16:40:44吗?

标签: java datetime timezone


【解决方案1】:

这里的问题是 DateFormat 类有一个时区。试试这个例子:

    SimpleDateFormat sdfgmt = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
    sdfgmt.setTimeZone(TimeZone.getTimeZone("GMT"));

    SimpleDateFormat sdfmad = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
    sdfmad.setTimeZone(TimeZone.getTimeZone("Europe/Madrid"));

    String inpt = "2011-23-03 16:40:44";
    Date inptdate = null;
    try {
        inptdate = sdfgmt.parse(inpt);
    } catch (ParseException e) {e.printStackTrace();}

    System.out.println("GMT:\t\t" + sdfgmt.format(inptdate));
    System.out.println("Europe/Madrid:\t" + sdfmad.format(inptdate));

【讨论】:

  • 没有意识到 DateFormat 类有自己的时区。 Java 中的日期很混乱。
  • 抱歉回复晚了 ;) 但是 DateFormat 类有一个时区是有道理的,在不知道时区的情况下,表示某种日期形式的字符串并没有真正意义(至少没有时区)字符串中包含的信息),因此为了从简单的日期时间字符串转换为日期,您需要指定时区。
【解决方案2】:

这是 2017 年的答案。

    DateTimeFormatter dtf = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
    String inpt = "2011-03-23 16:40:44";

    ZonedDateTime madridTime = LocalDateTime.parse(inpt, dtf)
            .atOffset(ZoneOffset.UTC)
            .atZoneSameInstant(ZoneId.of("Europe/Madrid"));

    System.out.println("GMT:\t\t" + inpt);
    System.out.println("Europe/Madrid:\t" + madridTime.format(dtf));

请享受这段代码更自然地表达意图。

代码打印

GMT:        2011-03-23 16:40:44
Europe/Madrid:  2011-03-23 17:40:44

(标签大小为 8 时它对齐得很好,但 StackOverflow 似乎应用了 4 的标签大小)。

我在你的输入字符串中交换了2303,我相信你是故意的。顺便说一句,不是我发现你的错误,而是LocalDateTime.parse() 抛出异常,因为没有第 23 个月。同样在这方面,现代课程比过时的课程更有帮助。

Joda-Time? Basil Bourque’s answer 提到并推荐了我正在使用的 java.time 和 Joda-Time。虽然 Joda-Time 已经比问题中使用的过时类(SimpleDateFormatCalendarGregorianCalendar)有了相当大的改进,但它现在处于维护模式;预计不会有更大的进一步发展。 java.time 受到 Joda-Time 的极大启发。对于新代码,我认为您没有理由不喜欢 java.time

【讨论】:

    【解决方案3】:

    对于输入,您可以简单地将时区添加到字符串中(注意格式中的“z”):

    new SimpleDateFormat ("yyyy-MM-dd HH:mm:ss z").parse ("2011-23-03 16:40:44 GMT");
    

    【讨论】:

    • 也适用于 java7(这在 2021 年真是不可思议)
    【解决方案4】:

    最简单的方法是使用一个不错的日期时间库,而不是使用臭名昭著的麻烦的 java.util.Date 和 .Calendar 类。而是使用 Joda-Time 或 Java 8 中的 java.time 包。

    乔达时间

    String input = input.replace( " ", "T" ).concat( "Z" ) ; // proper ISO 8601 format for a date-time in UTC.
    DateTimeZone timeZone = DateTimeZone.forID( "Europe/Madrid" );
    DateTime dateTime = new DateTime( input, timeZone );
    String output = dateTime.toString();
    

    【讨论】:

      【解决方案5】:

      您需要在SimpleDateFormat 上设置TimeZone,使用DateFormat.setTimeZone()

      【讨论】:

        猜你喜欢
        • 2019-10-24
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2011-12-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2020-03-08
        相关资源
        最近更新 更多