时区问题: -北京、重庆、香港、乌鲁木齐(GMT 8)
在调试中获取上述时区的Id:- [南极洲/凯西,亚洲/文莱,亚洲/赤塔,亚洲/乔伊巴尔桑,亚洲/重庆,亚洲/重庆、亚洲/哈尔滨、亚洲/香港,亚洲/伊尔库茨克,亚洲/吉隆坡,亚洲/古晋,亚洲/澳门,亚洲/澳门、亚洲/望加锡、亚洲/马尼拉、亚洲/上海,亚洲/新加坡、亚洲/台北、亚洲/乌戎班当、亚洲/乌兰巴托,亚洲/澳大利亚乌兰巴托/澳大利亚珀斯/西部,CTT,Etc/GMT-8,中国香港,新加坡]
问题:-tz.inDaylightTime(new Date())为id Asia/Choibalsan返回true 并给出3600000日光差。正因为如此,它的显示时间提前了一个小时给香港用户。因为它增加了3600000作为日间节能差异
这是错误的,因为香港时区没有夏令时。"tz.inDaylightTime()"应在此处返回false
这个issue即将在linux服务器JDK8上生产。
它正在使用JDK8在windows上的本地系统上工作。
我的参考代码:-
public static String setDateTimeInTimezone(Date date, String userTimeZone) {
int offset = parseTimeZone(userTimeZone);
DateFormat formatter = new SimpleDateFormat("MM/dd/yyyy HH:mm:ss");
int timezoneDSTSaving = 0;
String[] timeArray = TimeZone.getAvailableIDs(offset);
TimeZone tz=null;
for (int i = 0; i < timeArray.length; i++) {
tz = TimeZone.getTimeZone(timeArray[i]);
if (tz.inDaylightTime(new Date())) {
timezoneDSTSaving = tz.getDSTSavings();
}
if (timezoneDSTSaving != 0) {
break;
}
}
//formatter.setTimeZone(tz);
return formatter.format(new Date(date.getTime() + offset + timezoneDSTSaving));
}
public static int parseTimeZone(String userTimeZone) {
// Represent GMT String used to display user time zone.
final String gmtStringConstant = GMT_OFFSET_STRING;
// Represent 60 minute in a hour.
final int minutes = 60;
// Represent 60 seconds in minute.
final int seconds = 60;
// Represent 1000 milli seconds in second.
final int milliseconds = 1000;
int timezoneDifference = 0;
int gmtIndex = userTimeZone.indexOf(gmtStringConstant);
// If "(GMT" String is not found in timezone, return 0.
if (gmtIndex == -1) {
return timezoneDifference;
}
String timeZone = userTimeZone.substring(gmtIndex + gmtStringConstant.length(), userTimeZone.length() - 1);
int indexOfColon = timeZone.indexOf(":");
if (indexOfColon != -1) {
int hourDiff = Integer.parseInt(timeZone.substring(0, indexOfColon)) * minutes * seconds * milliseconds;
int minDiff = Integer.parseInt(timeZone.substring(indexOfColon + 1)) * seconds * milliseconds;
if (hourDiff < 0) {
minDiff *= -1;
}
timezoneDifference = hourDiff + minDiff;
} else {
timezoneDifference = Integer.parseInt(timeZone) * minutes * seconds * milliseconds;
}
return timezoneDifference;
}
注意:我不想使用ZODATIME,我只想用util日期处理
tl;dr
- 夏令时在
Asia/Choibalsan
一直有效,直到2016年9月23日停止遵守。现在全年的偏移量是+08:00 - 您正在使用糟糕的日期-时间类,现在应该避免使用这些类
java.time
注意:我不想使用ZODATIME,我想用util-date-only 处理
可怕的java.util.Date
类在几年前被现代的java.time类所取代,直到JSR310被采用。
将所需时区指定为ZoneId
对象。
ZoneId z = ZoneId.of( "Asia/Choibalsan" ) ;
获取该区域的规则,该区域人民使用的偏移量的过去、现在和未来变化的历史。获取一个ZoneRules
对象。
ZoneRules rules = z.getRules() ;
指定要确定夏令时是否有效的时刻。你在2016年4月6日12:32问了这个问题,所以让我们利用这一时刻。
LocalDate ld = LocalDate.of( 2016 , Month.APRIL , 6 ) ;
LocalTime lt = LocalTime.of( 12 , 32 ) ;
ZonedDateTime zdt = ZonedDateTime.of( ld , lt , z ) ;
zdt.toString():
通过提取Instant
调整为UTC。
Instant instant = zdt.toInstant() ; // Extract a `Instant`, adjusting from time zone to UTC.
询问夏令时当时是否在该区域生效。
boolean inDst = rules.isDaylightSavings( instant ) ;
并询问夏令时调整的金额(如果夏令时生效)。
Duration d = rules.getDaylightSavings( instant ) ;
请参阅IdeOne.com上实时运行的代码。
zdt.toString():2016-04-06T12:32+09:00〔亚洲/乔伊巴尔桑〕
instant.toString():2016-04-06T03:32:00Z
inDst.toString():真正的
我们得到的结果是,Asia/Choibalsan
此时确实处于夏令时。
让我们试试当下。
System.out.println(
ZoneId
.of( "Asia/Choibalsan" )
.getRules()
.isDaylightSavings(
Instant.now()
)
);
我们得到false
,而不是当前处于夏令时。这与Time.is网站的报告一致,该网站目前未处于夏令时,同时也声称+08:00
是Asia/Choibalsan
的全年补偿。
Asia/Choibalsan
在2016-09-23之后降低夏令时
这些结果与该网站的报告一致,即夏令时在该时区的遵守情况有所下降,最后一次夏令时转换发生在2016年9月23日。