Firefox333
Firefox333

Reputation: 93

Java TimeZone with DST

I have the following code:

    public static void main(String[] args) {
       DateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
   //get current date time with Date()
       Date date = new Date();
       String currentDate = dateFormat.format(date);

       final SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
         try {
            System.out.println(sdf.format(getSomeDate(currentDate,TimeZone.getTimeZone("Asia/Omsk"))));
         } catch (ParseException e) {
         // TODO Auto-generated catch block
         e.printStackTrace();
       }  
    }

    public static Date getSomeDate(final String str, final TimeZone tz) throws ParseException {
       final SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss");
       sdf.setTimeZone(tz);
       return sdf.parse(str);
    }

Now the problem with it is, if I use the timezone I want (which is "America/Chicago"), I get the completely wrong time. It does the current time +6 instead of -6.

So how would I be able to fix this, because now I have to put a timezone from GMT + 6 to get the correct time & date for my program.

Also, does Java automatically incorporates the DST settings? As this is used by people from all around the world so some with the different DST times, it's hard to keep the right time.

Upvotes: 2

Views: 1064

Answers (2)

Basil Bourque
Basil Bourque

Reputation: 338256

java.time

The modern approach uses the java.time classes. You are using terrible date-time classes that were years ago outmoded with the adoption of JSR 310.

String input = "2020-01-23 15:00:00" ;

Such an input as this lacks an indicator of time zone or offset-from-UTC. So we must parse as an LocalDateTime. Such an object does not represent a moment, as we do not know if you mean 3 PM in Tokyo, Toulouse, or Toledo — very different moments several hours apart.

LocalDateTime ldt = LocalDateTime.parse( input.replace( " " , "T" ) ) ;

You seem to be certain this date and time were intended for the time zone of America/Chicago.

ZoneId z = ZoneId.of( "America/Chicago" ) ;
ZonedDateTime zdt = ZonedDateTime.of( ldt , z ) ;

Let's generate a string in standard ISO 8601 format to examine the offset in use in that zone at that moment. The ZonedDateTime::toString method wisely extends the standard to append the name of the zone in square brackets.

String output = zdt.toString() ;

output: 2020-01-23T15:00-06:00[America/Chicago]

Now we have determined a moment, in our ZonedDateTime object. We have a point on the timeline that in Chicago region appears to have the wall-clock time of 3 PM. This is six hours behind UTC, as we can see in the -06:00.

We can adjust to UTC by extracting an Instant object. This will make the time-of-day appear to jump ahead by six hours to 9 PM. Same moment, same point on the timeline, but different wall-clock time. Like two people talking on the phone from Iceland (which uses UTC as its time zone) and Chicago: if both look up at the clock on the wall simultaneously, one sees 3 PM while the other sees 6 PM.

Instant instant = zdt.toInstant() ;

instant.toString(): 2020-01-23T21:00:00Z

You asked about "people from all around the world so some with the different DST times". You can easily adjust the moment into other time zones. Perhaps someone in Tokyo wants to see the same moment in their time zone, several hours ahead of UTC rather than behind.

ZoneId zTokyo = ZoneId.of( "Asia/Tokyo" ) ;
ZonedDateTime zdtTokyo = zdt.withZoneSameInstant( zTokyo ) ; 

Or:

ZonedDateTime zdtTokyo = instant.atZone( z ) ;

zdtTokyo.toString(): 2020-01-24T06:00+09:00[Asia/Tokyo]

Notice how the date has jumped from 23rd to 24th, as well as the time-of-day jumping. Again, same simultaneous moment, different wall-clock time.

See this code run live at IdeOne.com.


Table of all date-time types in Java, both modern and legacy


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?

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.

Upvotes: 1

user1796756
user1796756

Reputation:

The problem, I suppose is that you set TimeZone for SimpleDateFormat only once in getSomeDate() method. Try to do this for all instances of SimpleDateFormat.

Upvotes: 0

Related Questions