Get TimeZone offset value from TimeZone without TimeZone name

JavaTimezone

Java Problem Overview


I need to save the phone's timezone in the format [+/-]hh:mm

I am using TimeZone class to deal with this, but the only format I can get is the following:

PST -05:00
GMT +02:00

I would rather not substring the result, is there any key or option flag I can set to only get the value and not the name of that timezone (GMT/CET/PST...)?

Java Solutions


Solution 1 - Java

> I need to save the phone's timezone in the format [+/-]hh:mm

No, you don't. Offset on its own is not enough, you need to store the whole time zone name/id. For example I live in Oslo where my current offset is +02:00 but in winter (due to [tag:dst]) it is +01:00. The exact switch between standard and summer time depends on factors you don't want to explore.

So instead of storing + 02:00 (or should it be + 01:00?) I store "Europe/Oslo" in my database. Now I can restore full configuration using:

TimeZone tz = TimeZone.getTimeZone("Europe/Oslo")

Want to know what is my time zone offset today?

tz.getOffset(new Date().getTime()) / 1000 / 60   //yields +120 minutes

However the same in December:

Calendar christmas = new GregorianCalendar(2012, DECEMBER, 25);
tz.getOffset(christmas.getTimeInMillis()) / 1000 / 60   //yields +60 minutes

Enough to say: store time zone name or id and every time you want to display a date, check what is the current offset (today) rather than storing fixed value. You can use TimeZone.getAvailableIDs() to enumerate all supported timezone IDs.

Solution 2 - Java

@MrBean - I was in a similar situation where I had to call a 3rd-party web service and pass in the Android device's current timezone offset in the format +/-hh:mm. Here is my solution:

public static String getCurrentTimezoneOffset() {
	
	TimeZone tz = TimeZone.getDefault();  
	Calendar cal = GregorianCalendar.getInstance(tz);
	int offsetInMillis = tz.getOffset(cal.getTimeInMillis());

	String offset = String.format("%02d:%02d", Math.abs(offsetInMillis / 3600000), Math.abs((offsetInMillis / 60000) % 60));
	offset = (offsetInMillis >= 0 ? "+" : "-") + offset;
	
	return offset;
} 

Solution 3 - Java

With java8 now, you can use

Integer offset  = ZonedDateTime.now().getOffset().getTotalSeconds();

to get the current system time offset from UTC. Then you can convert it to any format you want. Found it useful for my case. Example : https://docs.oracle.com/javase/tutorial/datetime/iso/timezones.html

Solution 4 - Java

With Java 8, you can achieve this by following code.

    TimeZone tz = TimeZone.getDefault();
    String offsetId = tz.toZoneId().getRules().getStandardOffset(Instant.now()).getId();

and the offsetId will be something like +01:00

Please notice the function getStandardOffset need a Instant as parameter. It is the specific time point, at which you want to check the offset of given timezone, as timezone's offset may varies during time. For the reason of some areas have Daylight Saving Time.

I think it is the reason why @Tomasz Nurkiewicz recommand not to store offset in signed hour format directly, but to check the offset each time you need it.

Solution 5 - Java

ZoneId here = ZoneId.of("Europe/Kiev");
ZonedDateTime hereAndNow = Instant.now().atZone(here);
String.format("%tz", hereAndNow);

will give you a standardized string representation like "+0300"

Solution 6 - Java

We can easily get the millisecond offset of a TimeZone with only a TimeZone instance and System.currentTimeMillis(). Then we can convert from milliseconds to any time unit of choice using the TimeUnit class.

Like so:

public static int getOffsetHours(TimeZone timeZone) {
    return (int) TimeUnit.MILLISECONDS.toHours(timeZone.getOffset(System.currentTimeMillis()));
}

Or if you prefer the new Java 8 time API

public static ZoneOffset getOffset(TimeZone timeZone) { //for using ZoneOffsett class
    ZoneId zi = timeZone.toZoneId();
    ZoneRules zr = zi.getRules();
    return zr.getOffset(LocalDateTime.now());
}

public static int getOffsetHours(TimeZone timeZone) { //just hour offset
    ZoneOffset zo = getOffset(timeZone);
    TimeUnit.SECONDS.toHours(zo.getTotalSeconds());
}

Solution 7 - Java

java.time: the modern date-time API

You can get the offset of a timezone using ZonedDateTime#getOffset.

Note that the offset of a timezone that observes DST changes as per the changes in DST. For other places (e.g. India), it remains fixed. Therefore, it is recommended to mention the moment when the offset of a timezone is shown. A moment is mentioned as Instant.now() and it represents the date-time in UTC (represented by Z which stands for Zulu and specifies the timezone offset of +00:00 hours).

Display offset of all timezones returned by ZoneId.getAvailableZoneIds():

import java.time.Instant;
import java.time.ZoneId;
import java.time.ZonedDateTime;

public class Main {
	public static void main(String[] args) {
		// Test
		Instant instant = Instant.now();
		System.out.println("Timezone offset at " + instant);
		System.out.println("==============================================");
		ZoneId.getAvailableZoneIds()
			.stream()
			.sorted()
			.forEach(strZoneId -> System.out.printf("%-35s: %-6s%n",
				strZoneId, getTzOffsetString(ZoneId.of(strZoneId), instant)));
	}

	static String getTzOffsetString(ZoneId zoneId, Instant instant) {
		return ZonedDateTime.ofInstant(instant, zoneId).getOffset().toString();
	}
}

Output:

Timezone offset at 2021-05-05T21:45:34.150901Z
==============================================
Africa/Abidjan                     : Z     
Africa/Accra                       : Z     
Africa/Addis_Ababa                 : +03:00
...
...
...    
W-SU                               : +03:00
WET                                : +01:00
Zulu                               : Z  

Learn more about the 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.

Solution 8 - Java

I know this is old, but I figured I'd give my input. I had to do this for a project at work and this was my solution.

I have a Building object that includes the Timezone using the TimeZone class and wanted to create zoneId and offset fields in a new class.

So what I did was create:

private String timeZoneId;
private String timeZoneOffset;

Then in the constructor I passed in the Building object and set these fields like so:

this.timeZoneId = building.getTimeZone().getID();
this.timeZoneOffset = building.getTimeZone().toZoneId().getId();

So timeZoneId might equal something like "EST" And timeZoneOffset might equal something like "-05:00"

I would like to not that you might not

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionMr BeanView Question on Stackoverflow
Solution 1 - JavaTomasz NurkiewiczView Answer on Stackoverflow
Solution 2 - JavaPuguaSoftView Answer on Stackoverflow
Solution 3 - JavavoidMainReturnView Answer on Stackoverflow
Solution 4 - JavaSuNView Answer on Stackoverflow
Solution 5 - JavaДмитрий КулешовView Answer on Stackoverflow
Solution 6 - JavaMeetTitanView Answer on Stackoverflow
Solution 7 - JavaArvind Kumar AvinashView Answer on Stackoverflow
Solution 8 - JavaCrislipsView Answer on Stackoverflow