-1
My approach :
// initailize date object
Date date = new Date();
// get time zone
ZoneId zoneId = ZoneId.of("Asia/Dubai");

// create zonedDateTime object
ZonedDateTime zdt = ZonedDateTime.ofInstant(date.toInstant(), zoneId);

// instant of zonedDateTime
Instant instant = zdt.toInstant();

// convert instant to specified zone
instant.atZone(zoneId);

// Get Local Date Time Object
LocalDateTime ldt = LocalDateTime.ofInstant(instant,zoneId);

//Convert it back to Date Object
Date dateFinal = java.util.Date.from(Instant.from(ldt.atZone(zoneId)));

Can anyone help me with conversion of timeZone Date object in Java 8 Date date = Fri Mar 31 16:10:13 IST. Now I need to convert this Date to any given timeZone Date object

Desired result:

Date resultDate = Fri Mar 31 14:40:13 GST

Basically here I used (Asia/Dubai) Time Zone

But my result is: 2023-03-31T16:10:13.854+0530. I am getting the result in IST only. It’s not getting converted to (Asia/Dubai).

I have mentioned all the ways I have tried.

Ole V.V.
  • 81,772
  • 15
  • 137
  • 161
  • 3
    `Date` does not contain a timezone. It represents a point in time, like `Instant`. This looks like an [XY Problem](http://xyproblem.info/). `date` and `dateFinal` will always be the same. How about using `zdt` as your final result? – Sweeper Mar 31 '23 at 11:24
  • 2
    Also, don't use mix the old and new APIs. `Date` is old, and you don't need it in most cases anymore. Use only the `java.time.*` types. – Matt Johnson-Pint Mar 31 '23 at 16:27
  • Since a `Date` with a specified time zone is impossible, don’t you simply want `ZonedDateTime.now(zoneId)`? – Ole V.V. Apr 01 '23 at 07:12
  • *But my result is: `2023-03-31T16:10:13.854+0530`.* I didn’t get that exactly. An old-fashioned `Date` did not print in that format. So how exactly did you get that? – Ole V.V. Apr 01 '23 at 07:18
  • Does this answer your question? [Convert date string (EST) to Java Date (UTC)](https://stackoverflow.com/questions/12919067/convert-date-string-est-to-java-date-utc) – Ole V.V. Apr 02 '23 at 08:03

1 Answers1

1

tl;dr

Core Concept: java.util.Date does not have a time zone. The Date#toString method lies to you.

If handed a legacy java.util.Date object, immediately convert to java.time.Instant.

Instant instant = myJavaUtilDate.toInstant() ;

Then apply your desired time zone.

ZonedDateTime zdt = instant.atZone( ZoneId.of( "Asia/Dubai" ) ) ;

Use only java.time

Your date-time handling should involve only the java.time classes.

The date-time classes outside that package are now legacy, terribly flawed in poor design. The legacy classes were supplanted by java.time in JSR 310, implemented in Java 8+.

You said:

// initailize date object
Date date = new Date();

Did you mean java.util.Date or java.sql.Date? Both are legacy.

  • The first was replaced by java.time.Instant. Both the legacy and modern classes represent a moment as seen with an offset from UTC of zero hours-minutes-seconds.
  • The second was replaced by java.time.LocalDate. The legacy class pretends to represent a date-only, but because of faulty design it actually contains a time-of-day and an assumption of an offset of zero. In contrast, the modern class truly represents a date-only, without time-of-day, and without time zone or offset.

Instead use this code:

Instant instant = Instant.now() ;  // Capture the current moment as seen in UTC (zero offset).

You said:

// get time zone
ZoneId zoneId = ZoneId.of("Asia/Dubai");

Good. A ZoneId is the modern way to represent a time zone. And Asia/Dubai, in Continent/Region is the correct naming for real time zones.

You said:

// create zonedDateTime object
ZonedDateTime zdt = ZonedDateTime.ofInstant(date.toInstant(), zoneId);

Using our Instant object seen above, use this code:

ZonedDateTime zdt = instant.atZone( zoneId ) ;

Both instant & zdt here represent the same simultaneous moment, the same point on the timeline. But the latter is viewed through the wall-clock time used by people in a particular region.

You said:

// instant of zonedDateTime
Instant instant = zdt.toInstant();

Yes, you can extract an Instant from a ZonedDateTime. But this code in unnecessary here as we already instantiate a Instant object to capture the current moment.

You said:

// convert instant to specified zone
instant.atZone(zoneId);

The problem here is that an Instant object, like all the java.time objects, is immutable. You can alter (“mutate”) the content of an Instant object after its creation. That moment is frozen forever.

Furthermore, calling Instant#atZone returns a fresh new ZonedDateTime object. We saw just that in our code earlier above. Your code shown above ignores the new ZonedDateTime object returned by atZone.

You said:

// Get Local Date Time Object
LocalDateTime ldt = LocalDateTime.ofInstant(instant,zoneId);

Two problem here:

  • You can more easily obtain a LocalDateTime from the ZonedDateTime instantiated above. LocalDateTime ldt = zdt.toLocalDateTime() ;
  • You may not be aware that in creating the LocalDateTime, you are discarding valuable information: the time zone. So you are left with merely a date and a time-of-day. But such a value is inherently ambiguous. For example, if noon on January 23 this year, we do not know if you meant in noon in Tokyo Japan, noon in Toulouse France, or noon in Toledo Ohio US — three very different moments several hours apart.

Tip: If you do not yet fully grok date-time handling, avoid using LocalDateTime. In most business situations, we generally care about a moment, a specific point on the timeline. LocalDateTime does not fit that case.

You said:

//Convert it back to Date Object
Date dateFinal = java.util.Date.from(Instant.from(ldt.atZone(zoneId)));

Two problems here:

  • You can more easily write java.util.Date.from( instant ) as we already have an Instant in hand. Or, if we had just the ZonedDateTime seen above, java.util.Date.from( zdt.toInstant() ).
  • You would usually never write this in new code. Convert to the legacy code only where necessary to interoperate with old code not yet updated to java.time. Otherwise, avoid both Date classes like the plague. Ditto for Calendar, SimpleDateFormat, etc.

Your title asks:

[Convert a Date object to a specified timeZone Date Object]

I do not understand what you mean. The java.util.Date class represents a moment in UTC. It has no time zone.

(Actually there is a time zone buried with its code, but this code is practically irrelevant, and represents another of those terrible design decisions found in the legacy date-time classes.)

You said:

timeZone Date object in JAVA 8 Date date = Fri Mar 31 16:10:13 IST

Do not be fooled by the java.util.Date#toString method. That method unfortunately injects the JVM’s current default time zone while generating text. While well-intentioned, this creates the false illusion that Date includes a time zone in its meaning when in fact it is "in UTC" (has an offset from UTC of zero).

Basil Bourque
  • 303,325
  • 100
  • 852
  • 1,154