Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/371.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 如何从UTC时间计算墙时间+;时区ID?_Java_Timezone_Utc_Dst_Wall Time - Fatal编程技术网

Java 如何从UTC时间计算墙时间+;时区ID?

Java 如何从UTC时间计算墙时间+;时区ID?,java,timezone,utc,dst,wall-time,Java,Timezone,Utc,Dst,Wall Time,我一直在谷歌上搜索这个问题,但找不到清晰明确的文档 假设我有一个UTC时间和一个时区ID,在知道夏令时在一年中会发生变化的情况下,如何在Java中计算墙时间(=UTC时间+时区偏移量+夏令时) 我正在寻找一个经过测试的代码示例。谢谢。在java中使用Date时,内部总是使用UTC。时区包括DST设置,所以实际上非常简单 public static void main(String[] args) throws ParseException { String stringAugust =

我一直在谷歌上搜索这个问题,但找不到清晰明确的文档

假设我有一个UTC时间和一个时区ID,在知道夏令时在一年中会发生变化的情况下,如何在Java中计算墙时间(=UTC时间+时区偏移量+夏令时)


我正在寻找一个经过测试的代码示例。谢谢。

在java中使用Date时,内部总是使用UTC。时区包括DST设置,所以实际上非常简单

public static void main(String[] args) throws ParseException {
    String stringAugust = "2011-08-01 12:00:00";
    String stringNovember = "2011-11-01 12:00:00";

    // Outputting the time in Stockholm and Santiago
    // Stockholm has DST in August and not in November
    // Santiago has DST in November and not in August

    SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");

    // Parsing the Strings
    sdf.setTimeZone(TimeZone.getTimeZone("UTC"));
    Date dateAugust = sdf.parse(stringAugust);
    Date dateNovember = sdf.parse(stringNovember);

    // outputting the dates for Stockholm
    sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss Z");
    sdf.setTimeZone(TimeZone.getTimeZone("Europe/Stockholm"));
    System.out.println(sdf.format(dateAugust));
    System.out.println(sdf.format(dateNovember));

    // outputting the dates for Santiago
    sdf.setTimeZone(TimeZone.getTimeZone("America/Santiago"));
    System.out.println(sdf.format(dateAugust));
    System.out.println(sdf.format(dateNovember));

}
输出

2011-08-01 14:00:00 +0200
2011-11-01 13:00:00 +0100
2011-08-01 08:00:00 -0400
2011-11-01 09:00:00 -0300

当你说你有UTC时间时,我假设你把它放在
日历中(
日期
没有时区的概念,尽管有误导性的
toString()
)。如果您有时间,例如在
String
中,您可以轻松地解析它或日历实例,如下所示:

Calendar summer = new GregorianCalendar(DateUtils.UTC_TIME_ZONE);
summer.set(2011, Calendar.JUNE, 27, 9, 0, 0);
夏季
代表2011年6月27日UTC上午9:00。现在,您只需将时区从UTC更改为澳大利亚的Melbounre:

summer.setTimeZone(TimeZone.getTimeZone("Australia/Melbourne"));
我将使用
FastDateFormat
正确打印日期:

final FastDateFormat formatter = FastDateFormat.getDateTimeInstance(FastDateFormat.SHORT, FastDateFormat.SHORT);

System.out.println(formatter.format(summer));
墨尔本的时间是19:00(+10小时)。但将日期改为冬季:

Calendar winter = new GregorianCalendar(DateUtils.UTC_TIME_ZONE);
winter.set(2011, Calendar.DECEMBER, 27, 9, 0, 0);
System.out.println(formatter.format(winter));
墨尔本的时间突然变成了20:00(+11小时)

这一差异证明,更改
日历上的时区将DST考虑在内。在UTC时区的6月份,澳大利亚有冬天,因此他们不遵守DST

但在UTC的冬天,澳大利亚有夏天——他们通过将时钟移动一小时来切换到DST。这就是为什么冬季的时差为+11小时,而夏季的时差为+10小时的原因


但是等等!当考虑到多个时区观测DST时,它变得更加有趣。首先,我在欧洲/奥斯陆时区创建了相同的日期:

Calendar winter = new GregorianCalendar(TimeZone.getTimeZone("Europe/Oslo"));
winter.set(2011, Calendar.DECEMBER, 27, 9, 0, 0);
奥斯陆冬季的9:00是协调世界时8:00,墨尔本是19:00(+10小时)

但在夏天的同一时间:

Calendar summer = new GregorianCalendar(TimeZone.getTimeZone("Europe/Oslo"));
summer.set(2011, Calendar.JUNE, 27, 9, 0, 0);
实际上是协调世界时7:00和墨尔本17:00+8小时

不知何故,人们认为两个时区之间的差异总是恒定的(“奥斯陆和墨尔本之间的差异总是10小时”),这是的事实,特别是当考虑到不同的半球时

事实上,在冬季(无夏令时,UTC+1),在(UTC+11)中观测到夏令时。另一方面,虽然奥斯陆有夏季,观测到夏令时(UTC+2),但在墨尔本(UTC+10)未观测到夏令时。现在很明显,为什么根据一年中的不同日期,差异在8到10小时之间变化

还要记住,DST的第一天和最后一天不是全球的,而是为每个时区任意选择的。这意味着9小时的差异也是可能的(!)例如,查看今年4月1日