问题
I have a DateTime in the format of Tue, 30 Apr 2019 16:00:00 +0800
which is RFC 2822 formatted date
I need to convert this to the given timezone in the DateTime which is +0800
So if i summarized,
DateGiven = Tue, 30 Apr 2019 16:00:00 +0800
DateWanted = 01-05-2019 00:00:00
How can i achieve this in Java? I have tried the below code but it gives 08 hours lesser than the current time which is
30-04-2019 08:00:00
Code i tried
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) );
回答1:
You are on right approach but just use java-8 date time API module, first create DateTimeFormatter
with the input format representation
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("EEE, dd MMM yyyy HH:mm:ss Z");
And then use OffsetDateTime
to parse string with offset
OffsetDateTime dateTime = OffsetDateTime.parse("Tue, 30 Apr 2019 16:00:00 +0800",formatter);
And the call the toLocalDateTime()
method to get the local time
LocalDateTime localDateTime = dateTime.toLocalDateTime(); //2019-04-30T16:00
If you want the output in particular format again you can use DateTimeFormatter
localDateTime.format(DateTimeFormatter.ISO_LOCAL_DATE_TIME) //2019-04-30T16:00:00
Note : As @Ole V.V pointed in comment, after parsing the input string into util.Date you are getting the UTC
time
The class Date represents a specific instant in time, with millisecond precision.
So now if you convert the parsed date time into UTC
you get 2019-04-30T08:00Z
without offset, so you can use withOffsetSameInstant to convert it into any particular timezone
dateTime.withOffsetSameInstant(ZoneOffset.UTC)
回答2:
You misunderstood. According to RFC 2822 +0800
means that an offset of 8 hours 0 minutes has already been applied to the time compared to UTC. So the output you got was the correct GMT time.
java.time
I recommend you skip the old and outdated classes SimpleDateFOrmat
and Date
. It’s much nicer to work with java.time, the modern Java date and time API. Furthermore it has the RFC format built in, so we don’t need to write our own formatter.
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);
Output:
In Singapore: 2019-04-30T16:00+08:00[Asia/Singapore] In GMT: 2019-04-30T08:00Z
The built-in formatter is named RFC_1123_DATE_TIME
because the same format is used in multiple Requests for Comments (RFCs).
Links
- RFC 2822 Internet Message Format
- Oracle tutorial: Date Time explaining how to use java.time.
回答3:
with the help of @ole v.v's explanation i have separated the datetime value for two 1. time 2. timezone
then i used this coding to extract the datetime which is related to the given timezone
//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;
}
来源:https://stackoverflow.com/questions/58830202/java-date-time-conversion-to-given-timezone