【问题标题】:Java Date Time conversion to given timezoneJava 日期时间转换为给定时区
【发布时间】:2020-03-08 20:13:58
【问题描述】:

我有一个格式为Tue, 30 Apr 2019 16:00:00 +0800 的日期时间,即RFC 2822 formatted date

我需要将其转换为 DateTime 中的给定时区,即 +0800

所以如果我总结一下,

DateGiven = Tue, 30 Apr 2019 16:00:00 +0800
DateWanted = 01-05-2019 00:00:00

如何在 Java 中实现这一点? 我已经尝试了下面的代码,但它比当前时间少 08 小时,即

30-04-2019 08:00:00

我试过的代码

String pattern = "EEE, dd MMM yyyy HH:mm:ss Z";
SimpleDateFormat format = new SimpleDateFormat(pattern);
Date startDate = format.parse(programmeDetails.get("startdate").toString());

//Local time zone   
 SimpleDateFormat dateFormatLocal = new SimpleDateFormat("yyyy-MMM-dd HH:mm:ss");

//Time in GMT
Date dttt= dateFormatLocal.parse( dateFormatGmt.format(startDate) );

【问题讨论】:

  • 我建议你不要使用SimpleDateFormatDate。这些类设计不良且过时,尤其是前者,尤其是出了名的麻烦。而是使用来自java.time, the modern Java date and time APIOffsetDateTimeDateTimeFormatter

标签: java datetime timezone datetime-format timezone-offset


【解决方案1】:

您的方法正确,但只使用 java-8 日期时间 API 模块,首先使用输入格式表示创建 DateTimeFormatter

DateTimeFormatter formatter = DateTimeFormatter.ofPattern("EEE, dd MMM yyyy HH:mm:ss Z");

然后使用OffsetDateTime解析带偏移量的字符串

OffsetDateTime dateTime = OffsetDateTime.parse("Tue, 30 Apr 2019 16:00:00 +0800",formatter);

并调用toLocalDateTime()方法获取当地时间

LocalDateTime localDateTime = dateTime.toLocalDateTime();  //2019-04-30T16:00

如果您想再次以特定格式输出,您可以使用DateTimeFormatter

localDateTime.format(DateTimeFormatter.ISO_LOCAL_DATE_TIME)   //2019-04-30T16:00:00

注意:正如@Ole V.V 在评论中指出的那样,将输入字符串解析为util.Date 后,您将获得UTC 时间

Date 类表示特定的时间瞬间,精度为毫秒。

所以现在如果你将解析的日期时间转换为UTC,你会得到2019-04-30T08:00Z没有偏移,所以你可以使用withOffsetSameInstant将它转换为任何特定的时区

dateTime.withOffsetSameInstant(ZoneOffset.UTC)

【讨论】:

  • 感谢您的回答。我已经创建了编码并发布为我试图实现的目标的答案。
【解决方案2】:

你误会了。根据 RFC 2822 +0800 表示与 UTC 相比,时间偏移了 8 小时 0 分钟已经。所以你得到的输出是正确的 GMT 时间。

java.time

我建议您跳过旧的和过时的课程SimpleDateFOrmatDate。使用现代 Java 日期和时间 API 的 java.time 要好得多。此外,它内置了 RFC 格式,因此我们不需要编写自己的格式化程序。

    OffsetDateTime parsedDateTime = OffsetDateTime
            .parse("Tue, 30 Apr 2019 16:00:00 +0800",
                    DateTimeFormatter.RFC_1123_DATE_TIME);
    
    ZonedDateTime dateTimeInSingapore
            = parsedDateTime.atZoneSameInstant(ZoneId.of("Asia/Singapore"));
    System.out.println("In Singapore: " + dateTimeInSingapore);
    
    OffsetDateTime dateTimeInGmt
            = parsedDateTime.withOffsetSameInstant(ZoneOffset.UTC);
    System.out.println("In GMT:       " + dateTimeInGmt);

输出:

In Singapore: 2019-04-30T16:00+08:00[Asia/Singapore]
In GMT:       2019-04-30T08:00Z

内置格式化程序被命名为 RFC_1123_DATE_TIME,因为在多个请求评论 (RFC) 中使用相同的格式。

链接

【讨论】:

  • 非常感谢您的精彩解释。它真的帮助我构建了我的编码。无论如何,我想通过添加 +0800 将时间更改为 2019 年 4 月 30 日星期二 16:00:00 到 01-05-2019 00:00:00,正如你所说,我误解了当它的 RFC 时没有转换时间。我已经改变了我的编码,分别发送时区和时间。并开发了答案中的代码。
【解决方案3】:

在@ole v.v 的解释的帮助下,我将日期时间值分隔为两个 1次 2. 时区

然后我使用此编码来提取与给定时区相关的日期时间

//convert datetime to give timezone 
    private static String DateTimeConverter (String timeVal, String timeZone)
    {
        SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");


    SimpleDateFormat offsetDateFormat2 = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ssZ");

        offsetDateFormat2.setTimeZone(TimeZone.getTimeZone(timeZone));
        String result =null;
        try {
            result = offsetDateFormat2.format(format.parse(timeVal));
        } catch (java.text.ParseException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }

        return result;
    }

【讨论】:

    猜你喜欢
    • 2011-12-01
    • 1970-01-01
    • 1970-01-01
    • 2018-07-20
    • 1970-01-01
    • 2019-10-24
    • 2023-04-04
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多