如何在Java中获取GMT与特定日期和时区的时差?
确定特定时区是否在DST中非常简单:
boolean isIsraelInDST = TimeZone.getTimeZone("Israel").inDaylightTime(new Date());
如何获得实际时差?
答案 0 :(得分:21)
使用TimeZone.getRawOffset():返回添加到UTC以获取此时区的标准时间的时间量(以毫秒为单位)。由于此值不受夏令时影响,因此称为原始偏移。
如果您想要包含DST的偏移量,则使用TimeZone.getOffset(长日期)。您应该为方法提供具体日期,例如now - System.currentTimeMillis()
答案 1 :(得分:9)
我建议将夏季/冬季时间偏移量添加到getRawOffset:
TimeZone tz1 = TimeZone.getTimeZone("GMT");
TimeZone tz2 = TimeZone.getTimeZone("America/New_York");
long timeDifference = tz1.getRawOffset() - tz2.getRawOffset() + tz1.getDSTSavings() - tz2.getDSTSavings();
答案 2 :(得分:7)
我看到这是一个旧线程 - 但是因为我最近有类似的要求而添加了这个 - 这给出了基于CURRENT时间(毫秒来自纪元)的毫秒的实际差异。
TimeZone.getTimeZone("America/New_York").getOffset(Calendar.getInstance().getTimeInMillis())
答案 3 :(得分:7)
ZoneId.of( "Pacific/Auckland" ) // Specify a time zone.
.getRules() // Get the object representing the rules for all the past, present, and future changes in offset used by the people in the region of that zone.
.getOffset( Instant.now() ) // Get a `ZoneOffset` object representing the number of hours, minutes, and seconds displaced from UTC. Here we ask for the offset in effect right now.
.toString() // Generate a String in standard ISO 8601 format.
13:00
某某日期的第一时刻。
ZoneId.of( "Pacific/Auckland" )
.getRules()
.getOffset(
LocalDate.of( 2018 , Month.AUGUST , 23 ) // Specify a certain date. Has no concept of time zone or offset.
.atStartOfDay( ZoneId.of( "Pacific/Auckland" ) ) // Determine the first moment of the day on that date in that region. Not always `00:00:00` because of anomalies such as Daylight Saving Time.
.toInstant() // Adjust to UTC by extracting an `Instant`.
)
.toString()
12:00
其他答案已经过时了,因为TimeZone
类现已成为遗产。这个和其他麻烦的旧日期时间类被 java.time 时间类所取代。
现在我们使用ZoneId
,ZoneOffset
和ZoneRules
代替遗留TimeZone
类。
以continent/region
的格式指定proper time zone name,例如America/Montreal
,Africa/Casablanca
或Pacific/Auckland
。切勿使用诸如EST
或IST
之类的3-4字母缩写,因为它们不是真正的时区,不是标准化的,甚至不是唯一的(!)。
ZoneId z = ZoneId.of( "Africa/Tunis" ) ;
获取该区域的规则。
ZoneRules rules = z.getRules() ;
如果夏令时(DST)在某个时刻生效,请询问规则。将时刻指定为Instant
。 Instant
类代表UTC中时间轴上的一个时刻,分辨率为nanoseconds(小数部分最多九(9)位)。
Instant instant = Instant.now() ; // Capture current moment in UTC.
boolean isDst = rules.isDaylightSavings( instant ) ;
如何获得实际时差?
不确定你的意思,但我猜你在那个时刻要求offset-from-UTC生效。偏移量是UTC的小时,分钟和秒位移数。我们使用ZoneOffset
类表示偏移量。时区是特定地区人民使用的偏移的过去,现在和将来变化的历史。我们使用ZoneId
类表示时区。
因为某个地区的偏移可能会随时间而变化,所以我们必须在要求偏移时过一会儿。
ZoneOffset offset = rules.getOffset( instant ) ;
生成一个字符串,表示ISO 8601标准格式的偏移量。
String output output = offset.toString() ;
您可以要求将偏移量作为总秒数。
int offsetInSeconds = offset.getTotalSeconds() ;
java.time框架内置于Java 8及更高版本中。这些类取代了麻烦的旧legacy日期时间类,例如java.util.Date
,Calendar
和& SimpleDateFormat
现在位于Joda-Time的maintenance mode项目建议迁移到java.time类。
要了解详情,请参阅Oracle Tutorial。并搜索Stack Overflow以获取许多示例和解释。规范是JSR 310。
使用符合JDBC driver或更高版本的JDBC 4.2,您可以直接与数据库交换 java.time 对象。不需要字符串也不需要java.sql。* classes。
从哪里获取java.time类?
ThreeTen-Extra项目使用其他类扩展java.time。该项目是未来可能添加到java.time的试验场。您可以在此处找到一些有用的课程,例如Interval
,YearWeek
,YearQuarter
和more。
答案 4 :(得分:2)
public String timeZone(Date date) {
TimeZone timeZone = TimeZone.getTimeZone("America/New_York");
long millis = timeZone.getRawOffset() + (timeZone.inDaylightTime(date) ? timeZone.getDSTSavings() : 0);
return String.format("%s%s:%s",
millis < 0 ? "-" : "+",
String.format("%02d", Math.abs(TimeUnit.MILLISECONDS.toHours(millis))),
String.format("%02d", Math.abs(TimeUnit.MILLISECONDS.toMinutes(millis) - TimeUnit.HOURS.toMinutes(TimeUnit.MILLISECONDS.toHours(millis))))
);
}