Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/378.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/date/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 按时区偏移量获取时区_Java_Date_Datetime_Timezone_Timezone Offset - Fatal编程技术网

Java 按时区偏移量获取时区

Java 按时区偏移量获取时区,java,date,datetime,timezone,timezone-offset,Java,Date,Datetime,Timezone,Timezone Offset,我需要一个时区,并且我有时区偏移。 例如,我有offset=14400000。我想要一个时区(任何地方,任何城市)。我可以在SimpleDateFormat中使用此时区,因此它会打印此时区的正确时间 (我进行了一些重构): 我得到: sun.util.calendar.ZoneInfo[id="Asia/Baku",offset=14400000,dstSavings=0,useDaylight=false,transitions=68,lastRule=null] 我不喜欢这种方法,因为时区

我需要一个时区,并且我有时区偏移。

例如,我有offset=
14400000
。我想要一个时区(任何地方,任何城市)。我可以在
SimpleDateFormat
中使用此时区,因此它会打印此时区的正确时间

(我进行了一些重构):

我得到:

sun.util.calendar.ZoneInfo[id="Asia/Baku",offset=14400000,dstSavings=0,useDaylight=false,transitions=68,lastRule=null]
我不喜欢这种方法,因为
时区
将调用
区域信息文件
getZoneIds(int var1)
,在这里。这是反编译代码

 public static String[] getZoneIds(int var0) {
    ArrayList var1 = new ArrayList();
    String[] var2 = getZoneIds();
    int var3 = var2.length;

    for(int var4 = 0; var4 < var3; ++var4) {
        String var5 = var2[var4];
        ZoneInfo var6 = getZoneInfo(var5);
        if (var6.getRawOffset() == var0) {
            var1.add(var5);
        }
    }

    var2 = (String[])var1.toArray(new String[var1.size()]);
    Arrays.sort(var2);
    return var2;
}
publicstaticstring[]getZoneIds(int-var0){
ArrayList var1=新的ArrayList();
字符串[]var2=getZoneIds();
int var3=var2.length;
for(int var4=0;var4
您可以看到,它在现有对象上循环以构建区域ID数组,而我只需要一个


我的问题是,有没有更有效的方法?我只需要任何时区id或给定偏移量的单个时区。

您可以使用以下命令为任何偏移量构造时区实例:

该类与您通常使用它的类一起早已过时<代码>日历
格雷戈里安日历
日期格式
简化格式

我建议您开始使用
java.time
,这是一种现代的java日期和时间API。和他一起工作总的来说要好得多。然后,您需要一个时区的
ZoneId
对象。对于偏移量恒定的
ZoneId
,我们创建
ZoneOffset
的一个实例,它是
ZoneId
的两个子类之一

    int offsetMilliseconds = 14_400_000;
    int offsetSeconds = (int) TimeUnit.MILLISECONDS.toSeconds(offsetMilliseconds);
    // to check that we haven’t lost any precision, convert back to milliseconds and compare
    if (TimeUnit.SECONDS.toMillis(offsetSeconds) != offsetMilliseconds) {
        throw new IllegalArgumentException("Millisecond precision not supported: " + offsetMilliseconds);
    }
    ZoneId tzid = ZoneOffset.ofTotalSeconds(offsetMilliseconds / 1000);

    System.out.println(tzid);
    // test the time zone we got
    System.out.println(ZonedDateTime.now(tzid));
在我的电脑上,这是刚刚打印的:

+04:00
2018-01-16T19:44:22.863760+04:00
A的精度只有秒,而不是毫秒,这对于1440000毫秒的情况来说是很好的。如果您的毫秒数不等于整秒数,您可能希望舍入到整秒,而不是抛出异常,这是您的决定

只有当您需要将一个老式的
时区
对象传递给一些您现在无法更改或不想更改的旧API时,才可以转换上面的
时区ID

    TimeZone oldfashionedTimeZone = TimeZone.getTimeZone(tzid);
这将为您提供一个显示名称为GMT+04:00的
时区
,并且(当然)偏移4小时。但是,请注意,如果
时区
无法识别您试图转换到的时区(如果偏移量为奇数秒,则很可能是这种情况),它会默认为GMT(这只是旧类的一个问题)。因此,您可能应该检查得到的
时区
对象,例如:

    if (oldfashionedTimeZone.getRawOffset() != offsetMilliseconds) {
        throw new IllegalStateException("Conversion to legacy TimeZone object failed");
    }
tl;博士 不要做你正在尝试的事情

没有意义,因为在某一时刻共享偏移的分区在过去或将来的其他时刻可能不会共享该偏移

分区是偏移的历史记录 答案是正确的。这里有更多的讨论

我需要一个时区,我有时区偏移

不太可能

时间只不过是在时间之前或之后的小时数、分钟数和秒数

时区更重要。分区是特定区域的人民使用的过去偏移量变化的历史。分区还具有针对该区域偏移的当前和未来更改的规则。因此,一个时区总是比一个简单的偏移更可取,但只有当确定知道时才是如此。在你的情况下,你不知道区域,不应该猜测;只要坚持使用偏移量

给定的偏移量不能将您引导到特定时区,而不会产生歧义和错误

  • 模糊性,因为许多区域可能由于巧合而共享相同的偏移量。例如,
    Europe/Gibralter
    &
    Europe/Oslo
    &
    Africa/Lagos
    今天都共享相同的偏移量,比UTC提前一小时。因此,如果UTC的偏移量仅为
    +01:00
    ,您如何知道哪个是合适的
  • 错误,因为如果没有日期,您无法知道时区的偏移量。例如,上述三个区域在2017-2018年冬季共享相同的偏移量,但在夏季,直布罗陀和奥斯陆遵守夏令时(DST),这意味着它们将比UTC提前一小时,而拉各斯则比UTC提前一小时。从历史上看,由于世界各地的政治家都有重新定义区域的奇怪倾向,抵消可能会因为DST以外的其他原因而发生变化。例如,委内瑞拉在十年中两次将其补偿时间改为半小时。最近几年的另一个例子是,俄罗斯和土耳其一直在改变关于使用DST的想法,恢复到以前的静态偏移量,或者改变为永久保持在以前的静态偏移量之前
请注意,只有在提供作为参数传递的时刻(日期时间值)时,类才能为特定区域提供偏移量

ZoneOffset offset = ZoneId.of( "Africa/Tunis" )        // Instantiate a `ZoneId`.
                        .getRules()                    // Obtain a `ZoneRules` object from that `ZoneId` object.
                        .getOffset( Instant.now() ) ;  // Interrogate that `ZoneRules` for an offset-from-UTC in use at a specific moment in history.
我只需要任何时区id或给定偏移量的单个时区

这是不可取的。如上所述,在一个日期共享特定偏移的时区可能在另一个日期不共享该偏移。每个分区因其偏移量变化的历史而不同。因此,任意选择一个区域是不明智的

java.time 正如在另一个答案中所解释的那样,
时区
区域信息
类现在是遗留类。它们是被java.time类取代的麻烦的旧日期时间类的一部分

而是使用(与UTC的偏移量)和
ZoneId
(时区)

大陆/地区
的格式指定,例如,或
太平洋/奥克兰
。永远不要使用3-4个字母的缩写
    if (oldfashionedTimeZone.getRawOffset() != offsetMilliseconds) {
        throw new IllegalStateException("Conversion to legacy TimeZone object failed");
    }
ZoneOffset offset = ZoneId.of( "Africa/Tunis" )        // Instantiate a `ZoneId`.
                        .getRules()                    // Obtain a `ZoneRules` object from that `ZoneId` object.
                        .getOffset( Instant.now() ) ;  // Interrogate that `ZoneRules` for an offset-from-UTC in use at a specific moment in history.
ZoneId z = ZoneId.of( "America/Montreal" );