简体   繁体   English

如何从 android 设备获取 GMT 时区偏移量(如 GMT+7:00)?

[英]How to get the timezone offset in GMT(Like GMT+7:00) from android device?

I am getting the timezone of a android device using this code我正在使用此代码获取 android 设备的timezone

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.但它总是给我返回像“ IST ”这样的timezone区,但我想像GMT+7:00.一样获得GMT时区。

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") (时间单位是“java.util.concurrent.TimeUnit”)

This code return me GMT offset.此代码返回 GMT 偏移量。

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它返回这样的时区偏移: +0530

If we use SimpleDateFormat below如果我们在下面使用 SimpleDateFormat

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

It returns the time zone offset like this: GMT+05:30它返回这样的时区偏移: GMT+05:30

Here is a solution to get timezone offset in GMT+05:30 this format这是以GMT+05:30这种格式获取时区偏移的解决方案

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;
}
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返回+03:30

a one line solution is to use the Z symbol like:单行解决方案是使用Z符号,如:

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

where pattern could be: pattern可能是:

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

full reference here:完整参考在这里:

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

This is how Google recommends getting TimezoneOffset.这就是 Google 建议获取 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() https://developer.android.com/reference/java/util/Date#getTimezoneOffset()

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;
}
 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;

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);
}
TimeZone timeZone = TimeZone.getDefault();
String timeZoneInGMTFormat = timeZone.getDisplayName(false,TimeZone.SHORT);

Output : GMT+5:30输出:GMT+5:30

If someone is looking how to represent the GMT as a float number representing hour offset如果有人正在寻找如何将 GMT 表示为表示小时偏移的浮点数
(for example "GMT-0530" to -5.5), you can use this: (例如“GMT-0530”到-5.5),你可以使用这个:

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;

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);

Generally you cannot translate from a time zone like Asia/Kolkata to a GMT offset like +05:30 or +07:00.通常,您无法从亚洲/加尔各答等时区转换为 +05:30 或 +07:00 等 GMT 偏移量。 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).顾名思义,时区是地球上的一个地方,包括该地方人们使用的历史、现在和已知的未来 UTC 偏移量(现在我们可以将 GMT 和 UTC 视为同义词,严格来说它们不是) . 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).例如,亚洲/加尔各答自 1945 年以来一直处于 +05:30 偏移。在 1941 年至 1945 年期间,它位于 +06:30 和在那之前的 +05:53:20(是的,秒精度)。 Many other time zones have summer time (daylight saving time, DST) and change their offset twice a year.许多其他时区都有夏令时(夏令时,DST)并且每年更改两次偏移。

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 java.time 和 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() .对于默认的时区设置zoneZoneId.systemDefault()

To format the offset with the text GMT use a formatter with OOOO (four uppercase letter O) in the pattern:要使用文本GMT格式化偏移量,请在模式中使用带有OOOO (四个大写字母 O)的格式化程序:

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

GMT+05:30格林威治标准时间+05:30

I am recommending and in my code I am using java.time, the modern Java date and time API.我推荐并在我的代码中使用 java.time,现代 Java 日期和时间 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.许多其他答案中使用的TimeZoneCalendarDateSimpleDateFormatDateFormat类的设计很差,现在已经过时了,所以我的建议是避免所有这些类。

Question: Can I use java.time on Android?问题:我可以在 Android 上使用 java.time 吗?

Yes, java.time works nicely on older and newer Android devices.是的,java.time 在较旧和较新的 Android 设备上都能很好地工作。 It just requires at least Java 6 .它只需要至少Java 6

  • In Java 8 and later and on newer Android devices (from API level 26) the modern API comes built-in.在 Java 8 及更高版本和更新的 Android 设备(从 API 级别 26)中,现代 API 是内置的。
  • 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).在 Java 6 和 7 中获得 ThreeTen Backport,现代类的 backport(ThreeTen for JSR 310;请参阅底部的链接)。
  • On (older) Android use the Android edition of ThreeTen Backport.在(较旧的)Android 上使用 ThreeTen Backport 的 Android 版本。 It's called ThreeTenABP.它被称为 ThreeTenABP。 And make sure you import the date and time classes from org.threeten.bp with subpackages.并确保使用子包从org.threeten.bp导入日期和时间类。

Links链接

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 :)看看这是否有帮助:)

I stumbled upon a simple solution for this in Java8 (non-Android) using the ZoneDateTime class.我在 Java8(非 Android)中使用ZoneDateTime类偶然发现了一个简单的解决方案。 There may be other classes that implement the TemporalAccessor interface that work, but I haven't found them.可能还有其他实现TemporalAccessor接口的类可以工作,但我还没有找到它们。 This won't work with standard Date , DateTime , LocalDateTime , and Calender classes as far as I can tell.据我所知,这不适用于标准DateDateTimeLocalDateTimeCalender类。

    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.这个解决方案的好处是它避免了很多模数学、字符串生成和解析。

You can get your custom GMT time from this function from here您可以从这里使用此功能获取自定义 GMT 时间

  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);
    }

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?这似乎有效,但有没有更好的方法来获取设备的实际时间,该时间代表对用户有意义且准确的时间?

Adding dst offset will solve this:添加 dst 偏移量将解决这个问题:

    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;

Use this code ( Opt 1 ):使用此代码(选项 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:如果我在洛杉矶(GTM-07:00 太平洋标准时间),输出是:

timezone 1: GMT-07:00
timezone 2: PDT
timezone 3: PDT

To get date time with offset like 2019-07-22T13:39:27.397+05:00 Try following Kotlin code:要获取具有偏移量的日期时间,例如2019-07-22T13:39:27.397+05:00请尝试以下 Kotlin 代码:

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:如果您希望其他类似格式替换SimpleDateFormat模式,如下所示:

"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

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);
}

You can get the time zone offset formatted like +01:00 with following but two您可以获得格式为 +01:00 的时区偏移量,但有两个

  1. For API level 24+ then use XXX对于 API 级别 24+ 然后使用XXX
  2. For API level 24 or lower use ZZZZZ对于 API 级别 24 或更低使用ZZZZZ

To get result like this: 2011-12-03T10:15:30+01:00要获得这样的结果: 2011-12-03T10:15:30+01:00

you have to do:你必须做:

For Api level 24+ use " yyyy-MM-dd'T'HH:mm:ss.SSSXXX "对于 Api 级别 24+,请使用“ yyyy-MM-dd'T'HH:mm:ss.SSSXXX

For Api level below 24 use " yyyy-MM-dd'T'HH:mm:ss.SSSZZZZZ "对于 Api 级别低于 24使用“ yyyy-MM-dd'T'HH:mm:ss.SSSZZZZZ

The best solution that i found for myself我为自己找到的最佳解决方案

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

+03:00 +03:00

You can try to change pattern (the "xxx" string) to get the result you want, for example:您可以尝试更改模式(“xxx”字符串)以获得您想要的结果,例如:

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

+0300 +0300

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

+03 +03

Pattern can also apply another letters and the result will be different图案也可以应用其他字母,结果会有所不同

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

+0300 +0300

More about this you can find here: https://developer.android.com/reference/java/text/SimpleDateFormat.html有关更多信息,您可以在此处找到: https : //developer.android.com/reference/java/text/SimpleDateFormat.html

TimeZone timeZone = TimeZone.getTimeZone("GMT+7:00"); TimeZone timeZone = TimeZone.getTimeZone(“GMT + 7:00”);

declare it explicitely. 明确地宣布它。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM