Java日期时间到给定时区的转换

时间:2019-11-13 04:08:48

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

我有一个Tue, 30 Apr 2019 16:00:00 +0800格式的DateTime,它是RFC 2822 formatted date

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

所以,如果我总结一下,

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

3 个答案:

答案 0 :(得分:3)

使用正确的方法,但是只使用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)

答案 1 :(得分:2)

您误会了。根据RFC 2822,+0800表示与UTC相比,已经对时间应用了8小时0分钟的补偿。因此,您得到的输出是正确的GMT时间。

java.time

我建议您跳过旧的和过时的类SimpleDateFOrmatDate。与Java.time(现代的Java日期和时间API)一起使用会更好。此外,它具有内置的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)中使用了相同的格式。

链接

答案 2 :(得分:0)

借助@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;
    }