1

I have an issue where I tried all ways(including online stackoverflow threads), but am not able to set timezone as expected on a specific date. Here's my code:

Date until = DateTimeUtils.getNewBookUntilDate();
//which returns : Wed Aug 28 11:00:02 EDT 2019 

SimpleDateFormat isoFormat = new SimpleDateFormat("EEE MMM dd HH:mm:ss zzz yyyy");
            isoFormat.setTimeZone(TimeZone.getTimeZone("America/Los_Angeles");
try {
    until = isoFormat.parse(until.toString());
} catch (ParseException e) {
     e.printStackTrace();
}

But I still get : Wed Aug 28 11:00:02 EDT 2019 , instead of Wed Aug 28 8:00:02 PDT 2019

Any idea how to go about this?

sinclair
  • 2,812
  • 4
  • 24
  • 53
  • 2
    a Date doesn't have a timezone. Only when you create a string to represent it is the timezone taken into consideration. Look into where you are printing your date. – njzk2 Aug 28 '19 at 15:00
  • is there no other way I can retrieve the date that i have based on a current timezone and send it over? –  Aug 28 '19 at 15:02
  • Give try : set timezone in calendar then use. see this [example](http://www.java2s.com/Code/Java/Development-Class/TimeZonegetTimeZoneAmericaNewYork.htm) – Kishore Jethava Aug 28 '19 at 15:04
  • that doesnt seem to work either :( –  Aug 28 '19 at 15:24
  • It might help if you showed the code where you're converting to string / printing. – user1676075 Aug 28 '19 at 15:31
  • *send it over* — where to are you sending it and by what means? I’m sure there is a way. – Ole V.V. Aug 28 '19 at 17:51

1 Answers1

1

Avoid java.util.Date

A java.util.Date represents a moment in UTC. No need to manipulate it as text. Beware: the method Date::toString tells a lie, dynamically applying the JVM’s current default time zone while generating the text.

Instead, use java.time.Instant

First convert from that terrible legacy class to its modern replacement, java.time.Instant. Notice the new conversion methods added to the old classes.

Instant instant = myDate.toInstant() ;

ZonedDateTime

An Instant is also a moment in UTC. To see that same moment through the offset-from-UTC used by the people of a certain region, apply a ZoneId to get a ZonedDateTime object.

ZoneId z = ZoneId.of( "America/Montreal" ) ;
ZonedDateTime zdt = instant.atZone( z ) ;

Be clear: This zdt object and this instant object both represent the same moment, the same point on the timeline. They are different only in the wall-clock time. Imagine someone in Iceland (always in UTC) calling someone in Québec, and they both look up at the clock on their respective walls.

Converting from modern to legacy

If you have a ZonedDateTime object in hand, and you must get a java.util.Date for interoperating with old code not yet updated to java.time, you can convert. Go from an Instant to a Date, by extracting a Instant from your ZonedDateTime object.

Instant instant = zdt.toInstant() ;
java.util.Date date = java.util.Date.from ( instant ) ;

If you need a Calendar rather than Date, the conversion is more direct.

Calendar cal = GregorianCalendar.from( zdt ) ;

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.

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

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

You may exchange java.time objects directly with your database. Use a JDBC driver compliant with JDBC 4.2 or later. No need for strings, no need for java.sql.* classes.

Where to obtain the java.time classes?

Table of which java.time library to use with which version of Java or Android

Basil Bourque
  • 303,325
  • 100
  • 852
  • 1,154
  • thanks! how do i convert zonedatetime to date ? –  Aug 28 '19 at 18:05
  • @AngelaHeely I added a section at the end about converting from modern `ZonedDateTime` & `Instant` classes to the legacy class `java.util.Date`. – Basil Bourque Aug 28 '19 at 19:27
  • thanks Basil! you are the best! will check it out –  Aug 28 '19 at 20:21
  • why would you call that a lie? it's simply trying to represent that date in something that makes sense for the reader – njzk2 Aug 29 '19 at 02:35
  • @njzk2 The `Date` value is a moment in UTC. When you report that as being in a particular time zone, you create the illusion that there is a zone stored within the `Date`, when in fact there is not†. If you are storing a money amount in Canadian CAD yet report the amount adjusted into Japanese Yen without any request to do so, I believe any financial institution would consider that a lie. (†Actually there *is* a time zone buried deep within `Date`, but without getters/setters and not affecting `toString` yet affecting `equals` and such – making even more of a mess of a bloody awful class.) – Basil Bourque Aug 29 '19 at 03:11
  • Hey Basil, any idea about this : https://stackoverflow.com/questions/58186900/how-do-i-get-the-text-after-second-occurrence-of-the-character-of-my-string-us –  Oct 01 '19 at 14:38