-1

I am in +3 timezone now.
Now UTC time is 16:30 and at my place it is 19:30

I found an issue that for time zone America/Los_Angeles

which is theoretically -8 (rawOffset) I get unexpected time. I expected that if in my place 20:00, then at ths timezoe time should be 11 hours less(8+3) but in real life it is 10 hours less than in my place because of daylight saving.

So how can I get -7 offset if I have America/Los_Angeles zoneId in my code ?

TimeZone.getTimeZone("America/Los_Angeles").getRawOffset()/(3600*1000)

returns -8 but now it differs from UTC for 7 hours

enter image description here

gstackoverflow
  • 36,709
  • 117
  • 359
  • 710

2 Answers2

5

If you need to know the time zone offset that is correctly adjusted for DST, don't use getRawOffset(), since that is specifically the offset without DST. As the documentation says it:

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.

To know if DST is in effect, the system needs to know the date, not just the time. If you know the full date/time, then you can get the offset by calling e.g. getOffset(long date).

To get the time zone offset in effect right now, call:

int offset = TimeZone.getTimeZone("America/Los_Angeles")
                     .getOffset(System.currentTimeMillis());
int minutes = offset / 60000;

With the Java 8 Time API, the equivalent code is:

ZoneOffset offset = ZoneId.of("America/Los_Angeles")
                          .getRules().getOffset(Instant.now());
int minutes = offset.getTotalSeconds() / 60;
Andreas
  • 154,647
  • 11
  • 152
  • 247
2

java.time

The answer by Andreas is correct. This answer provides the solution using the modern Date-Time API.

The java.util Date-Time API and their formatting API, SimpleDateFormat are outdated and error-prone. It is recommended to stop using them completely and switch to the modern Date-Time API*, released in March 2014 as part of Java SE 8 standard library.

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

import java.time.ZoneId;
import java.time.ZoneOffset;
import java.time.ZonedDateTime;

public class Main {
    public static void main(String[] args) {
        ZoneOffset offset = ZonedDateTime.now(ZoneId.of("America/Los_Angeles")).getOffset();
        System.out.println(offset);
    }
}

Output:

-07:00

ONLINE DEMO

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
  • Actually, the Java 8 way of my answer is: `ZoneId.of("America/Los_Angeles").getRules().getOffset(Instant.now())` – Andreas Jun 11 '21 at 17:54