66

I am getting the timezone of a android device using this code

TimeZone tz = TimeZone.getDefault();
String current_Time_Zone = (TimeZone.getTimeZone(tz.getID()).getDisplayName(
                false, TimeZone.SHORT))

But it always return me the timezone like "IST" but i want to get the timezone in GMT like this GMT+7:00.

Naveen Kumar
  • 3,738
  • 4
  • 29
  • 50
  • 3
    It's not the timezone in GMT, It's called the offset from GMT. That may help you find the correct value. – Evert Feb 25 '13 at 13:33
  • IST is Different From GMT +05:30 by hours, you could calculate it later too. – Bigflow Feb 25 '13 at 13:36
  • @NaveenKumar If you know the IST, and GMT is always +05:30 hours. Then you always know the GMT too, right? But I guess that from Evert is better solution. (check my answer) – Bigflow Feb 25 '13 at 13:43
  • 1
    FYI, an [offset-from-UTC](https://en.wikipedia.org/wiki/UTC_offset) is a number of hours, minutes, and seconds – nothing more than that. A [time zone](https://en.wikipedia.org/wiki/Time_zone) is much more. A time zone is a history of past, present, and future changes to the offset used by the people of a particular region. – Basil Bourque Sep 08 '18 at 15:17

23 Answers23

85

This might give you an idea on how to implement it to your liking:

Calendar mCalendar = new GregorianCalendar();  
TimeZone mTimeZone = mCalendar.getTimeZone();  
int mGMTOffset = mTimeZone.getRawOffset();  
System.out.printf("GMT offset is %s hours", TimeUnit.HOURS.convert(mGMTOffset, TimeUnit.MILLISECONDS)); 

(TimeUnit is "java.util.concurrent.TimeUnit")

kaderud
  • 5,457
  • 2
  • 36
  • 49
  • 4
    I would just point out that if you are looking for an exact offset including daylight savings you should use mTimeZone.getOffset(currentTime) instead. – MikeL Jul 10 '16 at 18:19
  • 26
    This answer is *not* correct. rawOffset does not take daylight savings into account. To get the "real" offset you need: Calendar mCalendar = new GregorianCalendar(); TimeZone mTimeZone = mCalendar.getTimeZone(); int mGMTOffset = mTimeZone.getRawOffset() + (mTimeZone.inDaylightTime(new Date()) ? mTimeZone.getDSTSavings() : 0); – Grisgram Jul 22 '16 at 06:31
  • There are a number of cases where this will not work correctly. Summer time (DST) is one, another is when the offset is not a whole number of hours, as in the questioner’s time zone, for example. Also the classes `Calendar` , `GregorianCalendar` and `TimeZone` have later become long outdated and were always poorly designed. I recommend [java.time, the modern Java date and time API](https://docs.oracle.com/javase/tutorial/datetime/). – Ole V.V. Jul 22 '19 at 12:12
  • `int offsetInInteger = Integer.valueOf(offset.substring(0,3))` – paakjis Oct 14 '19 at 08:16
65

This code return me GMT offset.

Calendar calendar = Calendar.getInstance(TimeZone.getTimeZone("GMT"),
                Locale.getDefault());
Date currentLocalTime = calendar.getTime();
DateFormat date = new SimpleDateFormat("Z");
String localTime = date.format(currentLocalTime);

It returns the time zone offset like this: +0530

If we use SimpleDateFormat below

DateFormat date = new SimpleDateFormat("z",Locale.getDefault());
String localTime = date.format(currentLocalTime);

It returns the time zone offset like this: GMT+05:30

Naveen Kumar
  • 3,738
  • 4
  • 29
  • 50
  • 1
    @ErumHannan check this link http://stackoverflow.com/questions/16086962/how-to-get-a-time-zone-from-a-location-using-latitude-and-longitude-coordinates – Naveen Kumar Feb 18 '15 at 12:57
  • Actually the first 2 lines are unnecessary. You can simply replace "currentLocalTime" with "new Date()" to get the current time (the Date object is just a timestamp and contains no locale information). – BladeCoder Feb 19 '17 at 12:14
  • 4
    This is not working in Samsung s7 with Android 7.1(nougat) It retunrs *IST* not *GMT+05:30* Its working fine in lower version. – Jaydeep purohit Sep 18 '17 at 06:30
  • 2
    can confirm... instead of "GMT+01:00" I get "MEZ"... why is this so ridiculous complex – MilMike Feb 02 '19 at 09:45
29

Here is a solution to get timezone offset in GMT+05:30 this format

public 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 = "GMT"+(offsetInMillis >= 0 ? "+" : "-") + offset;

    return offset;
}
Yog Guru
  • 2,074
  • 3
  • 28
  • 47
22

a one line solution is to use the Z symbol like:

new SimpleDateFormat(pattern, Locale.getDefault()).format(System.currentTimeMillis());

where pattern could be:

  • Z/ZZ/ZZZ: -0800
  • ZZZZ: GMT-08:00
  • ZZZZZ: -08:00

full reference here:

http://developer.android.com/reference/java/text/SimpleDateFormat.html

Felipe Duarte
  • 1,079
  • 14
  • 20
21
public static String timeZone()
{
    Calendar calendar = Calendar.getInstance(TimeZone.getTimeZone("GMT"), Locale.getDefault());
    String   timeZone = new SimpleDateFormat("Z").format(calendar.getTime());
    return timeZone.substring(0, 3) + ":"+ timeZone.substring(3, 5);
}

returns like +03:30

XXX
  • 8,996
  • 7
  • 44
  • 53
10

This is how Google recommends getting TimezoneOffset.

Calendar calendar = Calendar.getInstance(Locale.getDefault());
int offset = -(calendar.get(Calendar.ZONE_OFFSET) + calendar.get(Calendar.DST_OFFSET)) / (60 * 1000)

https://developer.android.com/reference/java/util/Date#getTimezoneOffset()

Pavel
  • 2,610
  • 3
  • 31
  • 50
8
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;
}
PuguaSoft
  • 891
  • 7
  • 3
6
 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;
KOUSIK daniel
  • 305
  • 1
  • 3
  • 11
5

Yet another solution to get timezone offset:

TimeZone tz = TimeZone.getDefault();
String current_Time_Zone = getGmtOffsetString(tz.getRawOffset());

public static String getGmtOffsetString(int offsetMillis) {
    int offsetMinutes = offsetMillis / 60000;
    char sign = '+';
    if (offsetMinutes < 0) {
        sign = '-';
        offsetMinutes = -offsetMinutes;
    }
    return String.format("GMT%c%02d:%02d", sign, offsetMinutes/60, offsetMinutes % 60);
}
  • this is acually wrong as getRawOffset() returns offset from -8 UTC, not from UTC: http://developer.android.com/reference/java/util/TimeZone.html – Dmide Mar 16 '16 at 15:08
5
TimeZone timeZone = TimeZone.getDefault();
String timeZoneInGMTFormat = timeZone.getDisplayName(false,TimeZone.SHORT);

Output : GMT+5:30

Rajat Mehra
  • 1,462
  • 14
  • 19
5

Generally you cannot translate from a time zone like Asia/Kolkata to a GMT offset like +05:30 or +07:00. A time zone, as the name says, is a place on earth and comprises the historic, present and known future UTC offsets used by the people in that place (for now we can regard GMT and UTC as synonyms, strictly speaking they are not). For example, Asia/Kolkata has been at offset +05:30 since 1945. During periods between 1941 and 1945 it was at +06:30 and before that time at +05:53:20 (yes, with seconds precision). Many other time zones have summer time (daylight saving time, DST) and change their offset twice a year.

Given a point in time, we can make the translation for that particular point in time, though. I should like to provide the modern way of doing that.

java.time and ThreeTenABP

    ZoneId zone = ZoneId.of("Asia/Kolkata");

    ZoneOffset offsetIn1944 = LocalDateTime.of(1944, Month.JANUARY, 1, 0, 0)
            .atZone(zone)
            .getOffset();
    System.out.println("Offset in 1944: " + offsetIn1944);

    ZoneOffset offsetToday = OffsetDateTime.now(zone)
            .getOffset();
    System.out.println("Offset now: " + offsetToday);

Output when running just now was:

Offset in 1944: +06:30
Offset now: +05:30

For the default time zone set zone to ZoneId.systemDefault().

To format the offset with the text GMT use a formatter with OOOO (four uppercase letter O) in the pattern:

    DateTimeFormatter offsetFormatter = DateTimeFormatter.ofPattern("OOOO");
    System.out.println(offsetFormatter.format(offsetToday));

GMT+05:30

I am recommending and in my code I am using java.time, the modern Java date and time API. The TimeZone, Calendar, Date, SimpleDateFormat and DateFormat classes used in many of the other answers are poorly designed and now long outdated, so my suggestion is to avoid all of them.

Question: Can I use java.time on Android?

Yes, java.time works nicely on older and newer Android devices. It just requires at least Java 6.

  • In Java 8 and later and on newer Android devices (from API level 26) the modern API comes built-in.
  • In Java 6 and 7 get the ThreeTen Backport, the backport of the modern classes (ThreeTen for JSR 310; see the links at the bottom).
  • On (older) Android use the Android edition of ThreeTen Backport. It’s called ThreeTenABP. And make sure you import the date and time classes from org.threeten.bp with subpackages.

Links

Ole V.V.
  • 81,772
  • 15
  • 137
  • 161
4

If someone is looking how to represent the GMT as a float number representing hour offset
(for example "GMT-0530" to -5.5), you can use this:

Calendar calendar = new GregorianCalendar();
TimeZone timeZone = calendar.getTimeZone();
int offset = timeZone.getRawOffset();
long hours = TimeUnit.MILLISECONDS.toHours(offset);
float minutes = (float)TimeUnit.MILLISECONDS.toMinutes(offset - TimeUnit.HOURS.toMillis(hours)) / MINUTES_IN_HOUR;
float gmt = hours + minutes;
MikeL
  • 5,385
  • 42
  • 41
3

You can do like this:

    TimeZone tz = TimeZone.getDefault();
    int offset = tz.getRawOffset();

    String timeZone = String.format("%s%02d%02d", offset >= 0 ? "+" : "-", offset / 3600000, (offset / 60000) % 60);
Franzé Jr.
  • 1,194
  • 13
  • 20
2
TimeZone tz = TimeZone.getDefault();  
String gmt1=TimeZone.getTimeZone(tz.getID())
      .getDisplayName(false,TimeZone.SHORT);  
String gmt2=TimeZone.getTimeZone(tz.getID())
      .getDisplayName(false,TimeZone.LONG); Log.d("Tag","TimeZone : "+gmt1+"\t"+gmt2);

See if this helps :)

Sufian
  • 6,405
  • 16
  • 66
  • 120
sachinsharma
  • 195
  • 1
  • 12
2

I stumbled upon a simple solution for this in Java8 (non-Android) using the ZoneDateTime class. There may be other classes that implement the TemporalAccessor interface that work, but I haven't found them. This won't work with standard Date, DateTime, LocalDateTime, and Calender classes as far as I can tell.

    ZoneOffset myOffset = ZonedDateTime.now().getOffset();
    ZoneOffset myOffset2 = ZoneOffset.from(ZonedDateTime.now());
    log.info("ZoneOffset is " + myOffset.getId());  // should print "+HH:MM"
    log.info("ZoneOffset2 is " + myOffset2.getId());  // should print "+HH:MM"

The nice thing about this solution is that it avoids a lot of modulo math, string generation, and parsing.

saarp
  • 1,931
  • 1
  • 15
  • 28
  • 1
    `OffsetDateTime` works too and may be more correct to use than `ZonedDateTime`. The code works on older Android API levels too when you add [ThreeTenABP](https://github.com/JakeWharton/ThreeTenABP) to your Android project and import the date-time classes from the `org.threeten.bp` package. – Ole V.V. Jul 22 '19 at 12:04
2

You can get your custom GMT time from this function from here

  public static String getCurrentDate() {
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy MM dd hh:mm a zzz");
        Date date = new Date();
        sdf.setTimeZone(TimeZone.getTimeZone("GMT+6:00"));
        return sdf.format(date);
    }
pavel
  • 1,603
  • 22
  • 19
1

I've been looking at this too and trying to work out how to apply timezone and DST. Here's my code.

    public long applyGMTOffsetDST(long time) {
    // Works out adjustments for timezone and daylight saving time

    Calendar mCalendar = new GregorianCalendar();  
    TimeZone mTimeZone = mCalendar.getTimeZone();  
    boolean dstBool = mTimeZone.getDefault().inDaylightTime( new Date() );
    // add an hour if DST active

    if (dstBool == true) {
        time = time + secondsPerHour;
    }
    // add offest hours
    int mGMTOffset = mTimeZone.getRawOffset();

    if (mGMTOffset > 0) {
        long offsetSeconds = secondsPerHour * mGMTOffset;
        time = time + offsetSeconds;
    }

    return time;
}

This seems to work, but is there a better way to get the actual time off the device which represents a time that is meaningful and accurate to the user?

Darnst
  • 91
  • 1
  • 7
1

Adding dst offset will solve this:

    int offsetInMillis = TimeZone.getDefault().getRawOffset()+TimeZone.getDefault().getDSTSavings();
    String offset = String.format("%02d:%02d", Math.abs(offsetInMillis / 3600000), Math.abs((offsetInMillis / 60000) % 60));
    offset = (offsetInMillis >= 0 ? "+" : "-") + offset;
    return offset;
Ravi Kumar
  • 71
  • 1
  • 8
1

Use this code (Opt 1):

    //Opt 1
    Calendar calendar = Calendar.getInstance(TimeZone.getTimeZone("GMT"),
            Locale.getDefault());
    Date currentLocalTime = calendar.getTime();
    DateFormat date = new SimpleDateFormat("Z", Locale.getDefault());
    String localTime = date.format(currentLocalTime);
    String finalTimezone = String.format("GMT%s:%s", localTime.substring(0, 3), localTime.substring(3));
    Log.d(TAG, "timezone 1: " + finalTimezone);

    //Opt 2
    date = new SimpleDateFormat("z",Locale.getDefault());
    localTime = date.format(currentLocalTime);
    Log.d(TAG, "timezone 2: "+localTime);

    //Opt 3
    TimeZone tz = TimeZone.getDefault();
    Log.d(TAG, "timezone 3: "+tz.getDisplayName(true, TimeZone.SHORT));
    //

If I'm in Los Angeles (GTM-07:00 Pacific Standard Time) the output is:

timezone 1: GMT-07:00
timezone 2: PDT
timezone 3: PDT
Artificioo
  • 704
  • 1
  • 9
  • 19
1

To get date time with offset like 2019-07-22T13:39:27.397+05:00 Try following Kotlin code:

fun getDateTimeForApiAsString() : String{
    val date = SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSSXXX", 
                   Locale.getDefault())
    return date.format(Date())
}

Output Formate:

2019-07-22T13:39:27.397+05:00 //for Pakistan

If you want other similar formats replace pattern in SimpleDateFormat as below:

"yyyy.MM.dd G 'at' HH:mm:ss z"  //Output Format: 2001.07.04 AD at 12:08:56 PDT
"EEE, MMM d, ''yy"  //Output Format:    Wed, Jul 4, '01
"h:mm a"      //Output Format: 12:08 PM
"hh 'o''clock' a, zzzz"   //Output Format:  12 o'clock PM, Pacific Daylight Time
"K:mm a, z"  //Output Format:   0:08 PM, PDT
"yyyyy.MMMMM.dd GGG hh:mm aaa"  //Output Format:    02001.July.04 AD 12:08 PM
"EEE, d MMM yyyy HH:mm:ss Z"  //Output Format:  Wed, 4 Jul 2001 12:08:56 -0700
"yyMMddHHmmssZ"  //Output Format:   010704120856-0700
"yyyy-MM-dd'T'HH:mm:ss.SSSZ"  //Output Format:  2001-07-04T12:08:56.235-0700
"yyyy-MM-dd'T'HH:mm:ss.SSSXXX"  //Output Format:    2001-07-04T12:08:56.235-07:00
"YYYY-'W'ww-u"  //Output Format:    2001-W27-3
Wajid
  • 2,235
  • 1
  • 19
  • 29
  • Please don’t teach the young ones to use the long outdated and notoriously troublesome `SimpleDateFormat` class. At least not as the first option. And not without any reservation. Today we have so much better in [`java.time`, the modern Java date and time API,](https://docs.oracle.com/javase/tutorial/datetime/) and its `DateTimeFormatter`. Yes, you can use it on Android. For older Android see [How to use ThreeTenABP in Android Project](https://stackoverflow.com/questions/38922754/how-to-use-threetenabp-in-android-project). – Ole V.V. Jul 22 '19 at 11:02
1

The best solution that i found for myself

SimpleDateFormat("XXX", Locale.getDefault()).format(System.currentTimeMillis())

+03:00

You can try to change pattern (the "xxx" string) to get the result you want, for example:

SimpleDateFormat("XX", Locale.getDefault()).format(System.currentTimeMillis())

+0300

SimpleDateFormat("X", Locale.getDefault()).format(System.currentTimeMillis())

+03

Pattern can also apply another letters and the result will be different

SimpleDateFormat("Z", Locale.getDefault()).format(System.currentTimeMillis())

+0300

More about this you can find here: https://developer.android.com/reference/java/text/SimpleDateFormat.html

0

I have a correct way:

public static String getCurrentTimeZone() {
    TimeZone timeZone = TimeZone.getDefault();
    return createGmtOffsetString(true, true, timeZone.getRawOffset());
}

public static String createGmtOffsetString(boolean includeGmt,
                                           boolean includeMinuteSeparator, int offsetMillis) {
    int offsetMinutes = offsetMillis / 60000;
    char sign = '+';
    if (offsetMinutes < 0) {
        sign = '-';
        offsetMinutes = -offsetMinutes;
    }
    StringBuilder builder = new StringBuilder(9);
    if (includeGmt) {
        builder.append("GMT");
    }
    builder.append(sign);
    appendNumber(builder, 2, offsetMinutes / 60);
    if (includeMinuteSeparator) {
        builder.append(':');
    }
    appendNumber(builder, 2, offsetMinutes % 60);
    return builder.toString();
}

private static void appendNumber(StringBuilder builder, int count, int value) {
    String string = Integer.toString(value);
    for (int i = 0; i < count - string.length(); i++) {
        builder.append('0');
    }
    builder.append(string);
}
0

You can get the time zone offset formatted like +01:00 with following but two

  1. For API level 24+ then use XXX
  2. For API level 24 or lower use ZZZZZ

To get result like this : 2011-12-03T10:15:30+01:00

you have to do :

For Api level 24+ use "yyyy-MM-dd'T'HH:mm:ss.SSSXXX"

For Api level below 24 use "yyyy-MM-dd'T'HH:mm:ss.SSSZZZZZ"

Rajesh Satvara
  • 3,842
  • 2
  • 30
  • 50