首页 > 解决方案 > 将日期转换为 GMT

问题描述

我想将日期转换为 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

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

标签: javadate

解决方案


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);
}

Date2019 年 6 月 26 日星期三 13:30:13 BST试试吧:

    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. 然后从那里进行任何进一步的转换。更改时区和保持日期和时间(小时-分钟-秒)的关键是类的withZoneSameLocal方法ZonedDateTime

我建议为格式化程序指定语言环境。

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

ADate没有,因为不能有时区。这是一个时间点,仅此而已。您的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 教程:解释如何使用 java.time 的日期时间。


推荐阅读