从TimeZone获取TimeZone偏移值而不使用TimeZone名称

Mr *_*ean 51 java timezone

我需要以[+/-] hh:mm格式保存手机的时区

我正在使用TimeZone类来处理这个问题,但我能得到的唯一格式如下:

PST -05:00
GMT +02:00
Run Code Online (Sandbox Code Playgroud)

我宁愿不对结果进行子串,是否有任何键或选项标志我可以设置为只获取值而不是该时区的名称(GMT/CET/PST ...)?

Tom*_*icz 87

我需要以[+/-] hh:mm格式保存手机的时区

不,你没有.抵消它本身是不够的,你需要存储整个时区名称/ ID.例如,我住在奥斯陆,我当前的偏移量是+02:00,但是在冬天(由于),它是+01:00.标准时间和夏令时之间的确切切换取决于您不想探索的因素.

因此,我存储在我的数据库中而不是存储+ 02:00(或应该存储+ 01:00?)"Europe/Oslo".现在,我可以使用以下方法恢

TimeZone tz = TimeZone.getTimeZone("Europe/Oslo")
Run Code Online (Sandbox Code Playgroud)

想知道今天我的时区偏移量是多少?

tz.getOffset(new Date().getTime()) / 1000 / 60   //yields +120 minutes
Run Code Online (Sandbox Code Playgroud)

然而在12月同样如此:

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

足以说:存储时区名称或ID,每次要显示日期时,检查当前偏移(今天)是什么,而不是存储固定值.您可以使用TimeZone.getAvailableIDs()枚举所有支持的时区ID.

  • 不,我正在与api进行交互,不管它的设计是好还是坏.我们不要进入那个.他们要求我发送一个像hh:mm这样的时区......我知道. (4认同)
  • @MrBean:巧合的是我告诉你该怎么做:如果你已经有了'TimeZone`类,只需用当前日期调用`getOffset()`并将其从毫秒转换为分钟.然后格式化为`hh:mm`. (3认同)

小智 71

@MrBean - 我遇到了类似的情况,我必须调用第三方Web服务并以+/- hh:mm格式传递Android设备的当前时区偏移量.这是我的解决方案:

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;
} 
Run Code Online (Sandbox Code Playgroud)


voi*_*urn 8

现在使用java8,您可以使用

Integer offset  = ZonedDateTime.now().getOffset().getTotalSeconds();
Run Code Online (Sandbox Code Playgroud)

以获取当前系统时间与UTC的偏移量。然后,您可以将其转换为所需的任何格式。发现它对我的情况有用。示例:https : //docs.oracle.com/javase/tutorial/datetime/iso/timezones.html


小智 6

使用 Java 8,您可以通过以下代码实现此目的。

    TimeZone tz = TimeZone.getDefault();
    String offsetId = tz.toZoneId().getRules().getStandardOffset(Instant.now()).getId();
Run Code Online (Sandbox Code Playgroud)

并且offsetId将类似于 +01:00

请注意该函数getStandardOffset需要一个Instant作为参数。它是特定的时间点,您要检查给定时区的偏移量,因为时区的偏移量可能会随时间变化。因为有些地区有夏令时

我认为这就是为什么@Tomasz Nurkiewicz 建议不要直接以有符号小时格式存储偏移量,而是在每次需要时检查偏移量的原因。


Дми*_*шов 5

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

会给你一个标准化的字符串表示,比如“+0300”


Arv*_*ash 5

java.time:现代日期时间 API

您可以使用 获取时区的偏移量ZonedDateTime#getOffset

请注意,观察DST的时区偏移量会根据 DST 的变化而变化。对于其他地方(例如印度),它保持不变。因此,建议提及显示时区偏移的时刻。时刻被提及为Instant.now(),它表示 UTC 中的日期时间(用 表示,Z代表 Zulu 并指定+00:00小时的时区偏移量)。

显示返回的所有时区的偏移量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();
    }
}
Run Code Online (Sandbox Code Playgroud)

输出:

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  
Run Code Online (Sandbox Code Playgroud)

Trail: Date Time了解有关现代日期时间 API *的更多信息。


* 出于任何原因,如果您必须坚持使用 Java 6 或 Java 7,则可以使用ThreeTen-Backport,它将大多数java.time功能向后移植到 Java 6 和 7。如果您正在处理 Android 项目和 Android API level 仍然不符合 Java-8,请检查通过脱糖可用的 Java 8+ API以及如何在 Android 项目中使用 ThreeTenABP