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

Java日期时间到给定时区的转换,java,datetime,timezone,datetime-format,timezone-offset,Java,Datetime,Timezone,Datetime Format,Timezone Offset,我有一个日期时间格式为2019年4月30日星期二16:00:00+0800,即RFC 2822格式的日期 我需要将其转换为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 我试过的代码 您的方法是正确的

我有一个日期时间格式为2019年4月30日星期二16:00:00+0800,即
RFC 2822格式的日期

我需要将其转换为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
我试过的代码
您的方法是正确的,但只需使用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
如果您想再次以特定格式输出,可以使用

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

类日期表示特定的时间瞬间,精度为毫秒

因此,现在如果您将解析的日期时间转换为
UTC
,您将得到
2019-04-30T08:00Z
,而不带偏移量,因此您可以使用将其转换为任何特定时区

dateTime.withOffsetSameInstant(ZoneOffset.UTC)

你误解了。根据RFC 2822
+0800
的规定,与UTC相比,时间偏移量为8小时0分钟。因此,您得到的输出是正确的GMT时间

java.time 我建议您跳过旧的和过时的类
SimpleDateFOrmat
Date
。使用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);
输出:

内置的格式化程序名为
RFC\u 1123\u DATE\u TIME
,因为在多个注释请求(RFC)中使用相同的格式

链接
  • 解释如何使用java.time

在@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;
    }

我建议您不要使用
SimpleDateFormat
Date
。这些类设计得很糟糕,而且早已过时,其中前者尤其令人讨厌。而是使用来自的
OffsetDateTime
DateTimeFormatter
。非常感谢您的精彩解释。它确实帮助我构建了我的代码。无论如何,我想通过添加+0800将时间从2019年4月30日星期二16:00:00更改为2019年5月1日00:00:00,正如您所说,我误解了当其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
//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;
    }