java 从没有时区名称的时区获取时区偏移值

4ktjp1zp  于 2023-08-02  发布在  Java
关注(0)|答案(8)|浏览(185)

我需要以[+/-]hh:mm格式保存手机的时区
我使用TimeZone类来处理这个问题,但我能得到的唯一格式如下:

PST -05:00
GMT +02:00

字符串
我宁愿不子串的结果,有没有任何关键字或选项标志,我可以设置为只得到值,而不是该时区的名称(GMT/CET/PST...)?

p1iqtdky

p1iqtdky1#

我需要以[+/-]hh:mm格式保存手机的时区
不你不知道偏移量本身是不够的,您需要存储整个时区名称/ID。例如,我住在奥斯陆,我的当前偏移量是+02:00,但在冬天(由于dst),它是+01:00。标准时间和夏令时之间的确切切换取决于您不想探索的因素。
因此,与其存储+ 02:00(或者应该是+ 01:00?))我将"Europe/Oslo"存储在数据库中。现在,我可以使用以下命令恢复完整配置:

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

字符串
想知道我今天的时区偏移是多少吗?

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


12月也是一样:

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


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

2w3kk1z5

2w3kk1z52#

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

字符串

iqih9akk

iqih9akk3#

在Java 8中,你可以用途:

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

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

cngwdvgl

cngwdvgl4#

在Java 8中,您可以使用以下代码实现这一点。

  • 获取区域偏移的步骤
TimeZone tz = TimeZone.getDefault();
  String offsetId = tz.toZoneId().getRules().getStandardOffset(Instant.now()).getId();

字符串
offsetId会是类似+01:00的。
请注意,ZoneRules::getStandardOffset为您提供了在应用 Daylight Saving Time 之前的区域ID偏移量,因为区域ID的偏移量可能会随着时间的推移而发生变化,正如Javadoc中提到的那样。
获取此区域中指定时刻的标准偏移量。这样可以访问有关标准偏移如何随时间变化的历史信息。标准偏移量是在应用任何夏令时之前的偏移量。这通常是冬季适用的偏移量。

  • 使用DST获取当前偏移
TimeZone.getDefault().toZoneId().getRules().getOffset(Instant.now()).getId()


返回的标识符将返回此区域的实际偏移量。
获取在这些规则中的指定时刻适用的偏移量。从瞬时到偏移的Map很简单,每个瞬时只有一个有效的偏移。此方法返回该偏移量。
函数ZoneRules::getStandardOffset/ZoneRules::getOffset的工作方式,即它们需要Instant作为参数,因为需要特定的时间点来计算该区域的偏移。因为此区域的规则可能会随时间而更改。
例如,zone 可能已更改其时区,如Samoa in 2011。或者是改变夏令时政策的国家,比如韩国或日本过去做过的,也许未来欧洲的一些国家。
这就是为什么@Tomasz Nurkiewicz的答案建议不要直接以带符号的小时格式存储偏移量,而是让代码在每次需要时计算偏移量的原因。

其他API

ZoneId.systemDefault().getRules().getStandardOffset(Instant.now())
ZoneId.systemDefault().getRules().getOffset(Instant.now())
// ZonedDateTime don't expose the standard offset (i.e without DST)
ZonedDateTime.now().getOffset()

参考文献

wlp8pajw

wlp8pajw5#

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

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

nkoocmlb

nkoocmlb6#

* 现代日期-时间API*

您可以使用ZonedDateTime#getOffset来取得时区的位移。
请注意,观察DST的时区的偏移量会随着DST的变化而变化。对于其他地方(例如印度),它仍然是固定的。因此,建议提及显示时区偏移量的时刻。一个时刻被称为Instant.now(),它表示UTC中的日期-时间(由Z表示,它代表祖鲁语,并指定时区偏移量+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();
    }
}

字符串

输出:

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


如欲了解有关modern date-time API * 的更多信息,请访问**Trail: Date Time**。

1cklez4t

1cklez4t7#

我们可以很容易地得到一个TimeZone的毫秒偏移量,只需要一个TimeZone示例和System.currentTimeMillis()。然后,我们可以使用TimeUnit类将毫秒转换为任意时间单位。
像这样:

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

字符串

  • 或者如果您更喜欢新的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());
}

bgibtngc

bgibtngc8#

我知道这很老了,但我觉得我应该给予点建议。我不得不在工作中为一个项目这样做,这就是我的解决方案。
我有一个Building对象,它使用TimeZone类包含了Timezone,我想在一个新类中创建zoneId和offset字段。
我所做的就是创造:

private String timeZoneId;
private String timeZoneOffset;

字符串
然后在构造函数中,我传入Building对象并设置这些字段,如下所示:

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


所以timeZoneId可能等于“EST”,timeZoneOffset可能等于“-05:00”
我希望你不要

相关问题