Reputation: 422
My application gets a response from my server with the date and time of past events. My server, however, is in another time zone and here things get a bit tricky. Server time zone is UTC +01:00
, while mine is UTC +03:00
. When I receive responses from the server, they come with a timestamp in UTC +01:00
. First, I tried to receive the date as a String
, substring it, set its time zone and then return it in a proper time format and zone. (I cut the last 4 digits of the milisec, because the DateFormat
was invalid otherwise.)
private String getFormattedDate(String date) {
DateFormat serverDateFormat = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSSXXX");
DateFormat finalDateFormat = new SimpleDateFormat("dd-MM-yyyy HH:mm:ss");
Calendar calendar = Calendar.getInstance();
TimeZone timeZone = calendar.getTimeZone();
serverDateFormat.setTimeZone(timeZone);
String cutoutDate = date.substring(0,23);
String cutoutZone = date.substring(27, date.length());
String dateInProperFormat = cutoutDate + cutoutZone;
Date finalDate = serverDateFormat.parse(dateInProperFormat);
return finalDateFormat.format(finalDate);
}
This read and converted everything correctly:
Server response:
2018-04-30T07:26:55.1524511+01:00
-> Substringed response:2018-04-30T07:26:55.152+01:00
-> Final format:30-04-2018 09:26:55
However, the milisec were not always 7, so when that happened, I got an Unparsable date
error. This made me read the date not as a String
, but as a Date
instead. This cut the code to only 5 lines:
private String getFormattedDate(Date date) {
SimpleDateFormat finalDateFormat = new SimpleDateFormat("dd-MM-yyyy HH:mm:ss");
Calendar calendar = Calendar.getInstance();
TimeZone timeZone = calendar.getTimeZone();
finalDateFormat.setTimeZone(timeZone);
return finalDateFormat.format(date);
}
But now, the time is always in UTC +01:00
. I tried getting the timezone like this:
TimeZone timeZone = TimeZone.getDefault();
But that didn't change anything. What exactly am I doing wrong in my second approach? I am ready to share more of my code if needed.
Upvotes: 1
Views: 301
Reputation: 86296
private static DateTimeFormatter finalDateTimeFormatter
= DateTimeFormatter.ofPattern("dd-MM-uuuu HH:mm:ss");
private static ZoneId zone = ZoneId.of("Europe/Istanbul");
private static String getFormattedDate(String dateTime) {
return OffsetDateTime.parse(dateTime)
.atZoneSameInstant(zone)
.format(finalDateTimeFormatter);
}
Let’s try it out with the example server response from your question:
System.out.println(getFormattedDate("2018-04-30T07:26:55.1524511+01:00"));
This outputs the desired:
30-04-2018 09:26:55
Points to note:
OffsetDateTime.parse
accepts from 1 to 9 decimals on the seconds, so you don’t need to manipulate the string in any way before parsing.UTC +03:00
as a time zone. Use a time zone like Africa/Nairobi, Europe/Moscow, Asia/Qatar or what is appropriate. It documents better why you are doing what you are doing, and it’s future-proof in case the offset is changed. Which happens more often than you may like to think.Yes, java.time
works nicely on older and newer Android devices. It just requires at least Java 6.
org.threeten.bp
with subpackages.java.time
.java.time
was first described.java.time
to Java 6 and 7 (ThreeTen for JSR-310).Upvotes: 2
Reputation: 4520
try below code. It's a workaround solution
public String getFormattedDate(String date) {
DateFormat serverDateFormat = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSSXXX");
DateFormat finalDateFormat = new SimpleDateFormat("dd-MM-yyyy HH:mm:ss");
Calendar calendar = Calendar.getInstance();
TimeZone timeZone = calendar.getTimeZone();
serverDateFormat.setTimeZone(timeZone);
String[] splitTime=date.split("\\+");
String cutoutDate="";
if (splitTime[0].length()>23)cutoutDate = date.substring(0,23);
else cutoutDate=splitTime[0];
String cutoutZone = "+"+splitTime[1];
String dateInProperFormat = cutoutDate + cutoutZone;
Date finalDate = null;
try {
finalDate = serverDateFormat.parse(dateInProperFormat);
} catch (ParseException e) {
e.printStackTrace();
}
return finalDateFormat.format(finalDate);
}
Upvotes: 1