2

I want to get the real offset for a timezone.

My problem :

 TimeZone tz = TimeZone.getTimeZone("America/Toronto");
int test = tz.getRawOffset();

test = -18000000

-18000000/1000/3600 = -5 

Or if i go https://www.google.fr/search?q=horaire+toronto&oq=horaire+toro&aqs=chrome.1.69i57j0l5.3311j0j7&sourceid=chrome&ie=UTF-8

i see Toronto is on UTC-4.

Its written on documentation , that the method return brut offset.

But how i can get the real offset ?

Fabiitch
  • 51
  • 3
  • 1
    Another search with "toronto daylight savings" seems to indicate that they do have daylight savings applicable, and clocks are set forward in march... Worth looking into... – ernest_k Oct 22 '18 at 15:28
  • The `TimeZone` class is long outdated and the `getTimeZone` method that you use in particular can behave very surprisingly. I recommend you avoid the old date-time classes and learn to use [java.time, the modern Java date and time API,](https://docs.oracle.com/javase/tutorial/datetime/) instead. It is so much nicer to work with. – Ole V.V. Oct 22 '18 at 17:13

3 Answers3

4

getRawOffset doesn't take DST into account. It reflects standard time. From the docs:

Returns the amount of time in milliseconds to add to UTC to get standard time in this time zone. Because this value is not affected by daylight saving time, it is called raw offset.

Toronto is currently observing daylight saving time (until November 4th) so its current UTC offset is -4 hours, but that's -5 hours "standard" and +1 hour DST.

Now there's an inaccurate assumption there: that a time zone never changes its standard time. java.util.TimeZone is a relatively old and primitive representation; it would be better to use java.time.ZoneId instead, along with the rest of the java.time package.

If you must use java.util.TimeZone, then call getOffset(long) to get the UTC offset at a particular instant in time.

Jon Skeet
  • 1,421,763
  • 867
  • 9,128
  • 9,194
2

java.time

The java.util API is outdated and error-prone. It is recommended to stop using it completely and switch to the modern Date-Time API*.

Solution using java.time, the modern Date-Time API:

import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.time.Month;
import java.time.ZoneId;
import java.time.ZoneOffset;
import java.time.ZonedDateTime;

public class Main {
    public static void main(String[] args) {
        ZoneId zoneId = ZoneId.of("America/Toronto");
        LocalDateTime ldtDstOn = LocalDateTime.of(LocalDate.of(2018, Month.OCTOBER, 22), LocalTime.MIN);
        LocalDateTime ldtDstOff = LocalDateTime.of(LocalDate.of(2018, Month.NOVEMBER, 22), LocalTime.MIN);

        // Using ZonedDateTime
        ZoneOffset offsetDstOn = ZonedDateTime.of(ldtDstOn, zoneId).getOffset();

        // Alternatively, using ZoneId#getRules
        ZoneOffset offsetDstOff = zoneId.getRules().getOffset(ldtDstOff);

        System.out.println(offsetDstOn);
        System.out.println(offsetDstOff);
    }
}

Output:

-04:00
-05:00

ONLINE DEMO

Verify with Clock Changes in Toronto, Ontario, Canada 2018

Learn more about the modern Date-Time API* from Trail: Date Time.


* For any reason, if you have to stick to Java 6 or Java 7, you can use ThreeTen-Backport which backports most of the java.time functionality to Java 6 & 7. If you are working for an Android project and your Android API level is still not compliant with Java-8, check Java 8+ APIs available through desugaring and How to use ThreeTenABP in Android Project.

Arvind Kumar Avinash
  • 71,965
  • 6
  • 74
  • 110
0

Don't use getRawOffset

use : tz.getOffset(new Date().getTime()) / 1000 / 3600

Ivan Fontalvo
  • 433
  • 4
  • 21