Reputation: 790
In the UK, I'd like to get the current offset from UTC/GMT. Currently the offset is 1 hour, but there seems to be no way of finding this.
Code
TimeZone timeZone = TimeZone.getDefault();
logger.debug("Timezone ID is '" + timeZone.getID() + "'");
if (timeZone.getID().equals("GMT")) {
timeZone = TimeZone.getTimeZone("Europe/London");
logger.debug("New timezone is '" + timeZone.getID() + "'");
}
Long eventDateMillis = Long.parseLong(eventDateValue.getKeyValue());
int timezoneOffset = timeZone.getOffset(eventDateMillis);
logger.debug("Offset for " + eventDateValue + "(" + eventDateMillis + ") using timezone " + timeZone.getDisplayName() + " is " + timezoneOffset);
returns debug output
Wed 2012/09/19 16:38:19.503|Debug|DataManagement|Timezone ID is 'GMT'
Wed 2012/09/19 16:38:19.503|Debug|DataManagement|New timezone is 'GMT'
Wed 2012/09/19 16:38:19.557|Debug|DataManagement|Offset for 18 Sep 2012 09:00(1347958800000) using timezone Greenwich Mean Time is 0
In other words, timezone 'GMT' is returning an offset of zero and I can't find how to set it to something that does return the correct offset.
If someone can provide a working code sample for JodaTime, that would do but I'd really like to avoid having to install a separate library just for what should be a one-liner.
The Java version is 7.
Upvotes: 11
Views: 22089
Reputation: 79395
java.time.ZonedDateTime
has been designed to adjust the timezone offset automatically.
Demo:
import java.time.LocalDate;
import java.time.LocalTime;
import java.time.ZoneId;
import java.time.ZonedDateTime;
public class Main {
public static void main(String[] args) {
LocalTime time = LocalTime.of(10, 20);
ZoneId zoneId = ZoneId.of("Europe/London");
// A winter date-time
ZonedDateTime zdtWinter = ZonedDateTime.of(LocalDate.of(2020, 11, 22), time, zoneId);
System.out.println(zdtWinter);
// A summer date-time
ZonedDateTime zdtSummer = ZonedDateTime.of(LocalDate.of(2021, 07, 22), time, zoneId);
System.out.println(zdtSummer);
}
}
Output:
2020-11-22T10:20Z[Europe/London]
2021-07-22T10:20+01:00[Europe/London]
The Z
in the output is the timezone designator for zero-timezone offset. It stands for Zulu and specifies the Etc/UTC
timezone (which has the timezone offset of +00:00
hours).
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*. However, for any reason, if you need to convert an object of ZonedDateTime
to an object of java.util.Date
, you can do so as follows:
Date date = Date.from(zdtSummer.toInstant());
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.
Upvotes: 1
Reputation: 555
This made me the trick:
String zone = "Europe/London";
int plusHoursGMT = TimeZone.getTimeZone(zone).getRawOffset() / 3600000;
assertThat(plusHoursGMT, is(0));
Upvotes: 0
Reputation: 6846
Use timezone.getOffset( 0 ), instead of timezone.getOffset( eventDateMillis ).
This will give you the offset as of January 1st, 1970 GMT time, which in the case of Europe/London is 3600000, NOT zero due to historical issues with Wales and Northern Ireland.
Upvotes: 1
Reputation: 3063
I just encountered this myself.
I tried TimeZone.getTimeZone("London"); and it worked.
No I have no idea why - 'London' isn't one of the IDs TimeZone returns...
Upvotes: 2
Reputation: 1502076
In other words, timezone 'GMT' is returning an offset of zero and I can't find how to set it to something that does return the correct offset.
0 is the correct offset for GMT, permanently.
You want "Europe/London", which is the time zone which switches between GMT and BST.
EDIT: I hadn't originally noticed that you're trying to get Europe/London. It looks like the time zone database your JVM is using is basically messed up. You could either try fixing that, or simply use Joda Time which comes with its own copy of tzdb. Sample code:
DateTimeZone zone = DateTimeZone.forID("Europe/London");
long offset = zone.getOffset(new Instant());
System.out.println(offset); // 3600000
Upvotes: 15