In one of my projects, I have to convert UTC DateTime to user specific Date and Time. I am using xml to get time offset and daylight saving parameters.
for example offset="GMT+2" dst="true"
if this is the case, then I have to convert the utc DateTime to GMT+2 considering daylight saving.
I read many blog posts and articles but didnt fully understand how to do this time and date conversion. Can somebody please show me an example using JODA DateTime or anything similar in java.
Thanks,
If you have a DateTime instance in any given DateTimeZone you can convert it to another time zone with just dateTime.toDateTime(otherTimeZone).
Related
I want to format time like 19:19:00 to different time zones. If I use SimpleDateFormat it always takes into account the start of the epoch: 1970.01.01.
Some timezones have different offsets on the start of the epoch and now. For example, the default offset from Europe/Kiev now is UTC+0200 but in 1970 it was UTC+0300. That means if I run my server under Europe/Kiev the client which login under Europe/Berlin(UTC+0100) will see three hours different instead of two.
I can solve this problem by writing a custom formatter for java.sql.Time. But I want to ask maybe there are some common approach or Java tools/libraries which can solve it.
Another solution can be using joda-time:
TimeZone.setDefault(TimeZone.getTimeZone("Europe/Kiev"));
DateTimeZone.setDefault(DateTimeZone.forID("Europe/Kiev"));
DateTimeFormat.forPattern("HH:mm:ss.SSS")
.withZone(DateTimeZone.forID("Europe/Berlin"))
.print(Time.valueOf("19:00:00").getTime());
You can't format just a time to different time zones. You need a date.
If you want to assume that the date of that time is today, you can try this code:
ZoneId originalZone = ZoneId.of("Europe/Kiev");
ZoneId targetZone = ZoneId.of("Europe/Berlin");
LocalTime originalTime = LocalTime.parse("19:19:00");
LocalTime convertedTime = LocalDate.now(originalZone)
.atTime(originalTime)
.atZone(originalZone)
.withZoneSameInstant(targetZone)
.toLocalTime();
System.out.println(convertedTime);
Is java.time.instant an alternative for you? It handles all Timestamps internally as UTC-Time.
One way to parse it from a string is Instant.parse("2018-05-30T19:00:00")
If you want to have the time for a specific timezone you can get it with myInstant.atZone("Zone")
ZoneId originalZone = ZoneId.of("Europe/Kiev");
ZoneId targetZone = ZoneId.of("Europe/Berlin");
LocalDate assumedDate = LocalDate.now(originalZone);
String formattedTime = assumedDate.atTime(LocalTime.parse("19:19:00"))
.atZone(originalZone)
.withZoneSameInstant(targetZone)
.format(DateTimeFormatter.ofPattern("HH:mm:ss"));
System.out.println(formattedTime);
Today this printed:
18:19:00
When you know the date, you should of course use that instead of just today. In the case of Kyiv and Berlin I think they follow the same rules for summer time (DST), so the precise date may not be important. If converting between zones that don’t use the same transitions, or between a time zone that uses summer time and one that doesn’t, it’s suddenly crucial. And who knows in which of those two countries the politicians will change the rules next year? Better be safe.
Link: Oracle tutorial: Date Time explaining how to use java.time.
For example:
I know the date in UTC is 2020-05-15
I know the Time in
Pacific/Auckland (+12) is 8:00
How do I calculate the date in Pacific/Auckland (+12) with this known data?
I'd take the simple approach of "try the obvious date/time combination, and see whether it works":
Try a DateTime using the "UTC date" and local time, in the given time zone. In this case, you'd end up with 2020-05-15T08:00:00 in Pacific/Auckland
Convert that DateTime to UTC, in this case ending up with 2020-05-14T20:00:00Z
Check the resulting date:
Is it too early? Advance our candidate by one day.
Is it too late? Move our candidate back by one day.
Is it right? Great - our candidate was already correct.
Given a timezone (America/New_York), how do I go about getting the UTC offset?
I have tried using java.util.TimeZone but had no luck. I am fine with using Joda Time as well if the solution is viable in that.
The offset for a particular time zone can vary based on the current time because of daylight savings, etc. UTC doesn't have daylight savings, but "America/New_York" will change offsets with the daylight savings switch. Therefore, the offset is a function of both the current time and the timezone. The answers here give some examples of how to get the current offset:
Java TimeZone offset
Note: Current offset depends on
raw tz-offset
day-savings time (DST) for a CURRENT moment.
This is well described in near answer.
Useful snippets:
TimeZone.getTimeZone("Europe/Kiev").getOffset(Instant.now().toEpochMilli());
will give you integer offset in millisecons
String.format("%tz", Instant.now().atZone(ZoneId.of("Europe/Kiev")));
will give you a standardized string representation like "+0300"
I am pulling data from an external source into my program and it has an ISO8601 Date attached to it but one of our requirements is that the hour/minutes/seconds get set to zero. This happens before I receive the date. So I get this from the data.
2013-05-17T00:00:00.000Z
for instance. I am then putting that value into a Joda DateTime object called "businessDay". I do some processing based off of this value but then I need to persist it to MongoDB.
Since a Joda DateTime object is not serializable I need to put the DateTime object into a Date object and persist it to Mongo (and reverse that when it comes out).
When I use Joda in this way
businessDay.toDate() -- I receive a Java Date object but it is
Sun May 19 20:00:00 EDT 2013
and businessDay printed out normally is
2013-05-20T00:00:00.000Z
It converts it to my local time zone, which is then making it the previous day.
What I want is to convert the DateTime object into a Date object that retains the values.
I've been trying a bunch of things with DateTimeFormatter but I can't get it to work at all. I've also been deleting all of my efforts otherwise I would paste them here but I've been doing this all day to try to figure this out.
Thank you for any assistance.
EDIT:
Showing method that converts a String Date into a Joda DateTime object.
private DateTime asDateTime(String value) {
// Was experiencing an issue converting DateTime to date, it would convert to localtime zone
// giving me the wrong date. I am splitting the value into its year/month/day values and using a dateFormatter
// to give me an appropriate format for the date. Timezone is based on UTC.
String[] splitValue = value.split("-");
String[] splitDay = splitValue[2].split("T");
int year = Integer.parseInt(splitValue[0]);
int month = Integer.parseInt(splitValue[1]);
int day = Integer.parseInt(splitDay[0]);
DateTime date = new DateTime(DateTimeZone.UTC).withDate(year, month, day).withTime(0, 0, 0, 0);
return date;
}
Firstly, if you've just got a date, I would suggest using LocalDate rather than DateTime. However, I think you've misunderstood what java.util.Date does:
It converts it to my local time zone, which is then making it the previous day.
No, it really doesn't. Your DateTime value is precisely 2013-05-20T00:00:00.000Z. Now a java.util.Date is just a number of milliseconds since the Unix epoch. It doesn't have the concept of a time zone at all. It's equivalent to a Joda Time Instant.
When you call toString() on a Date, that converts the instant in time into your local time zone - but that's not part of the state of the object.
So both your DateTime and your Date represent midnight on May 20th UTC. I don't know what MongoDB is then doing with the value, but just the conversion from Joda Time to java.util.Date has not performed any time zone conversion for you.
My apologies, I found out that it wasn't an issue of the Dates it was a completely different issue. MongoDB can accept a Java Date and will convert it to UTC format automatically.
My fault for creating this post before looking at this problem from different angles.
Do I accept the other answer and give the bounty? Just curious if that is the correct thing to do on Stack Overflow.
Innovata publish the IATA Time Zone/Daylight Saving Time data for airline industry.
These files contains airport code, IATA Time Zone, start/stop date for UTC offset, UTC offset and longitude/latitude for the airport.
What is the best practice to convert an IATA Time Zone into Olson Db/Tz Database format or DateTimeZone for use with Joda Time?
Already added in a comment, but...
I suspect it would be easiest to just parse the file and create DateTimeZone instances via DateTimeZoneBuilder. You could also potentially implement ZoneInfoProvider if you didn't want to pass the zones around.
Have you considered converting the UTC offset to DateTimeZone instead?