【问题标题】:Converting date to GMT将日期转换为 GMT
【发布时间】:2019-06-26 12:25:25
【问题描述】:

我想将日期转换为 GMT。

我在 BST 中得到一个日期,我想将其转换为 GMT 而不进行时区转换。 例子: **如果 BST 日期是:Wed June 26 13:30:13 BST 2019

我想将其转换为 2019 年 6 月 26 日星期三 13:30:13 GMT**

我想忽略时区信息并返回与 GMT 相同的日期。

为此我正在尝试

        private SimpleDateFormat dateFormatLocal = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ssZ");
            private SimpleDateFormat dateFormatGmt = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ssZ");
            private SimpleDateFormat dateFormatGmtText = new SimpleDateFormat("EEE dd MMM yyyy HH:mm:ss 'GMT'");

              dateFormatGmt.setTimeZone(TimeZone.getTimeZone("GMT"));
          String textDate = dateFormatLocal.format(date);

//Date is Wed June 26 13:30:13 BST 2019
    private Date toGMTDate(final Date date) {
            String textDate = dateFormatLocal.format(date);
            try {
                String[] dateParts = textDate.split("\\+");
                textDate = dateParts[0] + "+0000";
                return dateFormatGmt.parse(textDate);
            } catch (ParseException e) {
                return null;
            }
        }

        private String toGMT(final Date date) {
            return dateFormatGmtText.format(toGMTDate(date));
        }

当我调用toGMT 时,它返回Wed 26 Jun 2019 14:30:13 GMT

我不知道为什么会这样? 这里有什么问题?

【问题讨论】:

  • A Date 只是自 unix 纪元以来的毫秒数。它没有时区。目前尚不清楚您的数据来自何处或采用何种格式,但这听起来像是在早期修复得更好。我还强烈建议使用 java.time 而不是 Date、SimpleDateFormat 等。
  • 我建议你不要使用SimpleDateFormat 和Date。这些类设计不佳且早已过时,尤其是前者,尤其是出了名的麻烦。而是使用ZonedDateTime、OffsetDateTime 和DateTimeFormatter,均来自java.time, the modern Java date and time API。
  • 您没有在 BST 中获得 Date,并且您无法在 GMT 中转换为 Date。老式的 Date 对象既不能有时区,也不能有 GMT 偏移量。
  • 我认为这是SimpleDateFormat returns wrong time zone during parse和其他问题的重复。
  • 既然你想要它作为一个字符串,为什么不直接用“GMT”替换字符串“BST”并完成它呢?

标签: java date


【解决方案1】:

java.time

您说您不能使用现代日期和时间 API,但对于其他读者,我想先介绍该选项。 SimpleDateFormat 和 Date 设计不佳且早已过时,前者尤其是出了名的麻烦,因此我建议避免使用它们。

我假设 BST 适用于英国夏令时(存在其他解释)。我假设你无法避免得到一个老式的Date 对象。

private static DateTimeFormatter formatter
        = DateTimeFormatter.ofPattern("EEE dd MMM yyyy HH:mm:ss z", Locale.UK);
private static ZoneId britain = ZoneId.of("Europe/London");
private static ZoneId gmt = ZoneId.of("Etc/GMT");

private static String toGMT(final Date date) {
    ZonedDateTime britishTime = date.toInstant().atZone(britain);
    ZonedDateTime gmtTime = britishTime.withZoneSameLocal(gmt);
    return gmtTime.format(formatter);
}

在 2019 年 6 月 26 日星期三 13:30:13 BST 的 Date 上试用一下:

    String textDate = dateFormatLocal.format(date);
    System.out.println(textDate);

    System.out.println(toGMT(date));

输出是:

2019-06-26T13:30:13+0100
Wed 26 Jun 2019 13:30:13 GMT

每当你得到一个老式的Date,首先要做的就是将它转换为Instant。然后从那里进行任何进一步的转换。 ZonedDateTime 类的 withZoneSameLocal 方法是更改​​时区和保持日期和时间(一天中的小时-分钟-秒)的关键。

我建议为格式化程序指定区域设置。

我不知道为什么会这样?这里有什么问题?

Date 没有,因为不能有时区。这是一个时间点,仅此而已。你的toGMTDate方法返回一个小时后的时间点:你给它的时间是13:30:13+0100,它返回的是13:30:13+0000,和14是同一个时间点:30:13+0100。接下来,您使用使用默认时区 Europe/London 的格式化程序格式化此时间点,因此生成 14:30:13,但同时在字符串中打印 GMT - 您报告的结果。

…新的时间库,但由于某些原因我不能使用它们。

如果你真的遇到了一个邪恶的老板,要么强迫你使用 Java 1.4 或 1.5 和/或禁止使用外部依赖项,那么非常简单的 hack 是:

private String toGMT(final Date date) {
    return dateFormatGmtText.format(date);
}

作弊是:您的dateFormatGmtText 使用您的默认时区欧洲/伦敦,但在格式化字符串中撒谎并打印GMT。这给出了与上面相同的输出——你要求的输出。与您的代码相比,我只是省略了日期转换。

链接: Oracle tutorial: Date Time 解释如何使用 java.time。

【讨论】:

    猜你喜欢
    • 2010-12-24
    • 1970-01-01
    • 2012-02-15
    • 2018-04-13
    • 2017-01-07
    • 1970-01-01
    • 2017-03-24
    • 2020-05-10
    • 2014-02-18
    相关资源
    最近更新 更多