Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Convert Joda-Time `DateTime` with timezone to DateTime without timezone?

Given a DateTime for example 2015-07-09T05:10:00+02:00 using Joda-Time?

How can I convert it to local time, meaning adding the timezone to the time itself. Desired output: 2015-07-09T07:10:00

I tried dateTime.toDateTime(DateTimeZone.UTC) but that did not give the desired result.

like image 807
membersound Avatar asked Nov 27 '22 04:11

membersound


1 Answers

Adding a bit more info and examples to the correct answers (accepted answer and other one).

UPDATE Added section at end on java.time classes. These supplant Joda-Time.

Purpose of LocalDateTime

You may be confused about the purpose of LocalDateTime.

If trying to represent a date-time value using "wall clock time" as seen by someone in a locality looking at their own clock and calendar, then adjust the time zone of the DateTime object to suit the desired locality.

LocalDateTime is not meant for a particular locality but for the general idea of date+time. For example, "This year's Christmas starts at midnight on December 25, 2014". Conceptually, that is a LocalDateTime, intended to mean different moments in Paris than Montréal and Auckland.

Adjusting Time Zone

Use the DateTimeZone class in Joda-Time to adjust to a desired time zone. Joda-Time uses immutable objects. So rather than change the time zone ("mutate"), we instantiate a new DateTime object based on the old but with the desired difference (some other time zone).

Use proper time zone names. Generally a continent/cityOrRegion.

DateTimeZone zoneParis = DateTimeZone.forID( "Europe/Paris" );
DateTimeZone zoneMontréal = DateTimeZone.forID( "America/Montreal" );
DateTimeZone zoneAuckland = DateTimeZone.forID( "Pacific/Auckland" );

Parse string, assign a time zone, adjust to other time zones.

DateTime dateTimeParis = new DateTime( "2015-07-09T05:10:00+02:00" , zoneParis );
DateTime dateTimeMontréal = dateTimeParis.withZone( zoneMontréal );
DateTime dateTimeAuckland = dateTimeParis.withZone( zoneAuckland );

Dump to console.

System.out.println( "dateTimeParis: " + dateTimeParis );
System.out.println( "dateTimeMontréal: " + dateTimeMontréal );
System.out.println( "dateTimeAuckland: " + dateTimeAuckland );

When run.

dateTimeParis: 2015-07-09T05:10:00.000+02:00
dateTimeMontréal: 2015-07-08T23:10:00.000-04:00
dateTimeAuckland: 2015-07-09T15:10:00.000+12:00

Localize Using Formatted Strings

Joda-Time can translate to a particular locale’s language and customary style when creating a string representation of your date-time object.

DateTimeFormatter formatterMontréal = DateTimeFormat.forStyle( "FF" ).withZone( zoneMontréal ).withLocale( Locale.CANADA_FRENCH );
String outputMontréal = formatterMontréal.print( dateTimeParis );
System.out.println( "outputMontréal: " + outputMontréal );

When run:

outputMontréal: mercredi 8 juillet 2015 23 h 10 EDT

java.time

The Joda-Time project, now in maintenance mode, advises migration to the java.time classes. The Joda-Time framework inspired java.time, so concepts are quite similar.

ZoneId and ZoneOffset are the two classes to represent a time zone and offset-from-UTC respectively. An offset is merely a number of hours and minutes and seconds. A time zone is an offset plus a set of rules for handling anomalies such as Daylight Saving Time (DST).

ZoneId zoneParis = ZoneId.of( "Europe/Paris" );
ZoneId zoneMontreal = ZoneId.of( "America/Montreal" );
ZoneId zoneAuckland = ZoneId.of( "Pacific/Auckland" );

The primary date-time classes in java.time are:

  • Instant – A moment on the timeline in UTC with a resolution of nanoseconds (up to nine (9) digits of a decimal fraction).
  • OffsetDateTime – An Instant plus a ZoneOffset.
  • ZonedDateTime – An Instant plus a ZoneId.

The java.time classes use ISO 8601 standard formats by default when parsing/generating strings representing date-time values. So no need to specify a formatting pattern with such inputs.

This input here indicates an offset-from-UTC but not a full time zone. So we parse as an OffsetDateTime rather than a ZonedDateTime.

OffsetDateTime odt = OffsetDateTime.parse( "2015-07-09T05:10:00+02:00" );

As the basic building-block of java.time, always in UTC by definition, you may want to extract an Instant.

Instant instant = odt.toInstant();  // `Instant` is always in UTC by definition.

You can adjust into a time zone.

ZonedDateTime zdtParis = odt.atZoneSameInstant( zoneParis );
ZonedDateTime zdtMontreal = odt.atZoneSameInstant( zoneMontreal );
ZonedDateTime zdtAuckland = zdtMontreal.withZoneSameInstant( zoneAuckland );

Localize via the DateTimeFormatter class.

DateTimeFormatter f = DateTimeformatter.ofLocalizedDateTime( FormatStyle.FULL ).withLocale( Locale.CANADA_FRENCH );
String output = zdtMontreal.format( f );

See live code in IdeOne.com.

odt: 2015-07-09T05:10+02:00

instant: 2015-07-09T03:10:00Z

zdtParis: 2015-07-09T05:10+02:00[Europe/Paris]

zdtMontreal: 2015-07-08T23:10-04:00[America/Montreal]

zdtAuckland: 2015-07-09T15:10+12:00[Pacific/Auckland]

output: mercredi 8 juillet 2015 23 h 10 EDT


About java.time

The java.time framework is built into Java 8 and later. These classes supplant the troublesome old legacy date-time classes such as java.util.Date, Calendar, & SimpleDateFormat.

The Joda-Time project, now in maintenance mode, advises migration to the java.time classes.

To learn more, see the Oracle Tutorial. And search Stack Overflow for many examples and explanations. Specification is JSR 310.

Where to obtain the java.time classes?

  • Java SE 8 and SE 9 and later
    • Built-in.
    • Part of the standard Java API with a bundled implementation.
    • Java 9 adds some minor features and fixes.
  • Java SE 6 and SE 7
    • Much of the java.time functionality is back-ported to Java 6 & 7 in ThreeTen-Backport.
  • Android
    • The ThreeTenABP project adapts ThreeTen-Backport (mentioned above) for Android specifically.
    • See How to use….

The ThreeTen-Extra project extends java.time with additional classes. This project is a proving ground for possible future additions to java.time. You may find some useful classes here such as Interval, YearWeek, YearQuarter, and more.

like image 189
Basil Bourque Avatar answered Dec 05 '22 18:12

Basil Bourque