我想获取洛杉矶的时区信息,现在10/10/2017是夏令时, 但是当我以两种方式在洛杉矶获得时区时,我得到了不同的结果。
public class TimeZoneDemo2 {
public static void main(String[] args) {
TimeZone timeZoneLosAngeles =
TimeZone.getTimeZone("America/Los_Angeles");
System.out.println(timeZoneLosAngeles);
TimeZone timeZoneGmtMinus07 = TimeZone.getTimeZone("GMT-07:00");
System.out.println(timeZoneGmtMinus07);
}
}
结果是:
sun.util.calendar.ZoneInfo [ID ="美国/洛杉矶",偏移= -28800000,dstSavings = 3600000,useDaylight =真,过渡= 185,lastRule = java.util.SimpleTimeZone中[ID =美洲/洛杉矶,偏移= -28800000,dstSavings = 3600000,useDaylight =真,startYear = 0,STARTMODE = 3,startMonth = 2,朝九特派= 8,startDayOfWeek = 1,开始时间= 7200000,startTimeMode = 0,endMode = 3, endMonth = 10,endday指定= 1,一个endDayOfWeek = 1,结束时间= 7200000,endTimeMode = 0]]
sun.util.calendar.ZoneInfo [ID =" GMT-07:00",偏移= -25200000,dstSavings = 0,useDaylight =假,过渡= 0,lastRule =空]
我的问题是:" America / Los_Angeles"获得的有关夏令时时区信息的信息。为什么不在" GMT -0700"?
获得的时区信息中包含夏令时信息(useDaylight = false)?答案 0 :(得分:9)
我想获取洛杉矶的时区信息,现在10/10/2017是夏令时
所以你应该要求" America / Los_Angeles"区。这就是它的用途。
" GMT-07:00" zone是一个固定偏移区域 - 它只适用于你想要表示"一个永久性地落后UTC七小时的时区"。 不适用于洛杉矶。
有很多其他时区有时在UTC-7 - 为什么你会期望GMT-07:00意味着"在洛杉矶观察到的时区" ?
换句话说,Java正在做正确的事情 - 它是你对GMT-07:00"" GMT-07:00"区域意味着不正确。
答案 1 :(得分:0)
Answer by Jon Skeet是正确的,应该被接受。您无法从UTC的偏移量可靠地确定时区,因为许多区域可能会同时共享偏移量。此外,区域的偏移量可能会随时间变化。
以下是一些代码示例,使用比问题中更多的现代类来解决问题。
你正在使用现在遗留下来的麻烦的旧日期时间类,取而代之的是java.time类。
正如其他人所述,如果您知道预期的时区,请始终优先使用该区域offset-from-UTC。偏移量只是UTC之前或之后的小时数,分钟数和秒数。时区是区域人员使用的偏移量变化的历史记录。时区知道过去,现在和(暂时)这种偏移变化的未来。
ZoneId
和ZoneOffset
类会替换TimeZone
。
以continent/region
的格式指定proper time zone name,例如America/Montreal
,Africa/Casablanca
或Pacific/Auckland
。切勿使用诸如EST
或IST
之类的3-4字母缩写,因为它们不是真正的时区,不是标准化的,甚至不是唯一的(!)。
ZoneId z = ZoneId.of( "America/Los_Angeles" ) ; // Or "Africa/Tunis", "Pacific/Auckland", etc.
通过该区域的镜头看到当前时刻。
ZonedDateTime zdt = ZonedDateTime.now( z ) ; // Fetch current moment for that zone.
提取相同的时刻,但调整为UTC。
Instant instant = zdt.toInstant() ; // Extract the same moment but in UTC.
将某个时刻调整到另一个区域。
ZonedDateTime zdtKolkata = instant.atZone( ZoneId.of( "Asia/Kolkata" ) ) ; // Determine same moment, same point on timeline, but in another time zone.
所有这三个对象代表时间轴上的同一个点,但以不同的挂钟时间查看。
查看当时该地区人民使用的偏移量。
ZoneOffset offset = z.getRules().getOffset( instant ) ; // Get the offset in place at that moment for that time zone.
您会发现,对于2018年,在该年的部分时间内,America/Los_Angeles
的偏移量将为-07:00
(超过UTC的服务时间)。在一年的另一部分,偏移量将是-08:00
(比UTC晚8小时)。这种抵消的变化是由于政治家决定观察Daylight Saving Time (DST)。
java.time框架内置于Java 8及更高版本中。这些类取代了麻烦的旧legacy日期时间类,例如java.util.Date
,Calendar
和& SimpleDateFormat
现在位于Joda-Time的maintenance mode项目建议迁移到java.time类。
要了解详情,请参阅Oracle Tutorial。并搜索Stack Overflow以获取许多示例和解释。规范是JSR 310。
从哪里获取java.time类?
ThreeTen-Extra项目使用其他类扩展java.time。该项目是未来可能添加到java.time的试验场。您可以在此处找到一些有用的课程,例如Interval
,YearWeek
,YearQuarter
和more。