首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Java时区转换意味着什么?

Java时区转换意味着什么?
EN

Stack Overflow用户
提问于 2017-01-18 15:22:50
回答 2查看 1.5K关注 0票数 5

我住在委内瑞拉,在过去的10年里,我们面临着格林尼治标准时间的2次变化。

此代码在Java 7更新76中运行

代码语言:javascript
复制
System.out.println(TimeZone.getTimeZone("America/Caracas"));

哪种指纹

代码语言:javascript
复制
sun.util.calendar.ZoneInfo[id="America/Caracas",offset=-16200000,dstSavings=0,useDaylight=false,transitions=5,lastRule=null]

当然,随着最新的JDK Java 8更新121,当然,在2016年年底,我们有了最新的变化。

代码语言:javascript
复制
sun.util.calendar.ZoneInfo[id="America/Caracas",offset=-14400000,dstSavings=0,useDaylight=false,transitions=6,lastRule=null]

我想知道转换意味着什么,文档说明了类似的内容。

不可以使用自定义时区ID指定夏时制转换计划

但在委内瑞拉,没有节省时间,我想知道,在这个特殊情况下,过渡意味着什么,是否意味着像gmt在历史上的总变化一样?

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2017-01-18 15:39:57

班级transitions字段有以下注释:

此数组描述此时区的GMT偏移量的转换,包括原始偏移量更改和夏时制更改。一个长整数由四个位字段组成。

尽管委内瑞拉没有DST,但它确实有一些与格林尼治时间相抵的变化。使用Linux命令zdump -v America/Caracas,可以获得以下输出:

代码语言:javascript
复制
America/Caracas  -9223372036854775808 = NULL
America/Caracas  -9223372036854689408 = NULL
America/Caracas  Wed Jan  1 04:27:43 1890 UT = Tue Dec 31 23:59:59 1889 LMT isdst=0 gmtoff=-16064
America/Caracas  Wed Jan  1 04:27:44 1890 UT = Wed Jan  1 00:00:04 1890 CMT isdst=0 gmtoff=-16060
America/Caracas  Mon Feb 12 04:27:39 1912 UT = Sun Feb 11 23:59:59 1912 CMT isdst=0 gmtoff=-16060
America/Caracas  Mon Feb 12 04:27:40 1912 UT = Sun Feb 11 23:57:40 1912 VET isdst=0 gmtoff=-16200
America/Caracas  Fri Jan  1 04:29:59 1965 UT = Thu Dec 31 23:59:59 1964 VET isdst=0 gmtoff=-16200
America/Caracas  Fri Jan  1 04:30:00 1965 UT = Fri Jan  1 00:30:00 1965 VET isdst=0 gmtoff=-14400
America/Caracas  Sun Dec  9 06:59:59 2007 UT = Sun Dec  9 02:59:59 2007 VET isdst=0 gmtoff=-14400
America/Caracas  Sun Dec  9 07:00:00 2007 UT = Sun Dec  9 02:30:00 2007 VET isdst=0 gmtoff=-16200
America/Caracas  Sun May  1 06:59:59 2016 UT = Sun May  1 02:29:59 2016 VET isdst=0 gmtoff=-16200
America/Caracas  Sun May  1 07:00:00 2016 UT = Sun May  1 03:00:00 2016 VET isdst=0 gmtoff=-14400
America/Caracas  9223372036854689407 = NULL
America/Caracas  9223372036854775807 = NULL

查看右边的gmtoff列。每一对线代表一个转换。你可以看到有更多的过渡,十多年前。

实际上,Java的做法有点不同。它只记录自1900年以来的过渡,因此1890年的偏移量不包括在内。但它在未来增加了一个虚拟的过渡。您可以看到以下代码(Java 8)的实际转换:

代码语言:javascript
复制
import java.lang.reflect.Field;
import java.time.Instant;
import java.util.TimeZone;

public class SimpleTest {

    public static void main(String[] args) {
        TimeZone tz = TimeZone.getTimeZone("America/Caracas");

        Field f = null;
        try {
            f = tz.getClass().getDeclaredField("transitions");
            f.setAccessible(true);
            long[] transitions = (long[]) f.get(tz);
            f = tz.getClass().getDeclaredField("offsets");
            f.setAccessible(true);
            int[] offsets = (int[]) f.get(tz);

            for ( long transition : transitions ) {
                Instant transitionInstant = Instant.ofEpochMilli(transition >> 12);
                int offset = offsets[(int)transition & 0xF];
                System.out.println( transitionInstant + " : " + offset);
            }
        } catch (NoSuchFieldException | SecurityException | IllegalArgumentException | IllegalAccessException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }

    }
}

产出如下:

代码语言:javascript
复制
1900-01-01T00:00:00Z : -16060000
1912-02-12T04:27:40Z : -16200000
1965-01-01T04:30:00Z : -14400000
2007-12-09T07:00:00Z : -16200000
2016-05-01T07:00:00Z : -14400000
2037-01-01T04:00:00Z : -14400000
票数 5
EN

Stack Overflow用户

发布于 2017-01-18 15:39:51

Transitions是一个数组,您只能得到它的长度(在本例中是6)

我引述如下:

此数组描述此时区的GMT偏移量的转换,包括原始偏移量更改和夏时制更改。一个长整数由四个位字段组成。最重要的52位字段表示从1970年1月1日到格林尼治时间00:00的转换时间(毫秒).下一个4位字段是保留的,必须是0.下一个4位字段是offsets[]的一个索引值,用于转换时的夏令量。如果此值为零,则意味着没有夏时制,而不是索引值为零。最不重要的4位字段是offsets[]在过渡时期的总偏移量的一个索引值。如果此时区不遵守夏令时,并且在过去从未更改过任何GMT偏移量,则此值为null。

在这里,[医]鹌鹑

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/41723123

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档