Java Daylight Saving Time Issues

I have a Java application that needs to be timezone aware. When I take the time of the Unix era and try to convert it to the timestamp used to call Oracle SQL, it gets the correct time zone, but the "useDaylightTime" value in the time zone is incorrect, i.e. It currently returns “true” when we are NOT in DST (I'm in Florida in the TZ “America / New York”).

This works on Red Hat Linux Enterprise 6, and as far as I can tell, it is correctly configured for the time zone, for example. Return 'date': Wed Nov 28 12:30:12 EST 2012

I also see, using the 'zdump' utility, that the current value for 'isdst' is 0.

My version of Java is 1.6.0_31.

I have googled this and have seen numerous problems that caused it, but many of them just say to install TZ manually, but my problem is not TZ, but the default TZ has "isDaylight" set to 'true '. I believe that this leads to the fact that my query returns data in one hour (I see that it is).

Here is a simple piece of code that I executed in order to try to reproduce it in the simplest way:

public class TZdefault { public static void main(String[] args) throws IOException { long startTime = System.currentTimeMillis()/1000; Calendar start = Calendar.getInstance(); start.setTimeInMillis(startTime); start.setTimeZone(TimeZone.getDefault()); System.out.println("Start UTC: " + start + "ms: " + start.getTimeInMillis()); System.out.println("use daylight: " + start.getTimeZone().useDaylightTime()); } // end main } // end class 

One last thing. If in my code I set TZ to "EST", it will of course return TZ with "isDaylight" set to False. But this is a bad decision.

I wanted to add a few details that I hoped to hide.

I have records in an Oracle 11g database that use TIMESTAMP with TIMEZONE fields. I just make JDBC queries where two parameters use a BETWEEN start timestamp and an end timestamp.

When I query this table, I use a prepared statement that uses a Calendar entry whose sole purpose was to try to manipulate the time zone. The bottom line is that I make a call to pstmt.setTimestamp () using the getTimeInMillis method to start and end the time when the default time zone was applied. Exiting the log shows that it actually puts the correct milliseconds, but the returned SQL results are clearly disabled for an hour for sure!

I'm still trying to verify that there is no problem on the data input side.

But I have a lot of debugging information, and it looks like I'm setting the right time in my JDBC request.

+6
source share
4 answers

useDaylightTime timezone useDaylightTime is incorrect, that is, it is currently being returned “true” when we are NOT in DST

I think you confuse useDaylightTime with inDaylightTime . The first tells you if there is a transition between daylight time and standard time in the future, and not which side of this transition you are on. For example, it returns false for Chinese time zones because China does not adjust daylight saving time, but it returns true for most US time zones, because most US states (except Arizona ) observe daylight saving time.

inDaylightTime

 public abstract boolean inDaylightTime(Date date) 

Requests if the specified date is in Daylight Saving Time in this time zone.

against

useDaylightTime

 public abstract boolean useDaylightTime() 

Requests if this TimeZone uses daylight saving time. If the base subclass of the TimeZone implementation supports historical and future daylight saving time changes, this method refers to the last known daylight saving time rule, which may be a future forecast and may not coincide with the current rule. Consider calling observesDaylightTime() if the current rule should also be taken into account.

+9
source

If you want to disable daylight saving time, you must set the time zone to EST. Otherwise, the time will be calculated based on the default time zone for AMERICA / NEW_YORK

  TimeZone zoneEST = TimeZone.getTimeZone("EST"); System.out.println(zoneEST.getDSTSavings()); //0 hour System.out.println(zoneEST.getRawOffset()); //5 hour TimeZone.setDefault(zoneEST); System.out.println(""); TimeZone zoneNY = TimeZone.getTimeZone("America/New_York"); System.out.println(zoneNY.getDSTSavings()); // 1 hour System.out.println(zoneNY.getRawOffset()); // 5 hour 
+5
source

I found a way to ensure that daylight saving time is ignored.

 TimeZone tz = TimeZone.getTimeZone("GMT"); TimeZone.setDefault(tz); GregorianCalendar calendar; calendar = new GregorianCalendar(); 

Set the time zone before creating the GregorianCalendar object

+3
source
 import java.text.ParseException; import java.text.SimpleDateFormat; import java.util.Date; import java.util.TimeZone; public class TimeZoneTest { public static void main(String[] argv) throws ParseException { SimpleDateFormat formatter = new SimpleDateFormat("dd-M-yyyy hh:mm:ss a"); String dateInString = "22-01-2015 10:15:55 AM"; Date date = formatter.parse(dateInString); TimeZone tz = TimeZone.getDefault(); // From TimeZone Asia/Singapore System.out.println("TimeZone : " + tz.getID() + " - " + tz.getDisplayName()); System.out.println("TimeZone : " + tz); System.out.println("Date : " + formatter.format(date)); // To TimeZone America/New_York SimpleDateFormat sdfAmerica = new SimpleDateFormat("dd-M-yyyy hh:mm:ss a"); TimeZone tzInAmerica = TimeZone.getTimeZone("America/New_York"); sdfAmerica.setTimeZone(tzInAmerica); String sDateInAmerica = sdfAmerica.format(date); // Convert to String first Date dateInAmerica = formatter.parse(sDateInAmerica); System.out.println("\nTimeZone : " + tzInAmerica.getID() + " - " + tzInAmerica.getDisplayName()); System.out.println("TimeZone : " + tzInAmerica); System.out.println("Date (String) : " + sDateInAmerica); System.out.println("Date (Object) : " + formatter.format(dateInAmerica)); } } 
+1
source

All Articles