我有一个时区值列表,就像我们在Windows时区下拉列表中看到的那样。
如果我们选择下拉列表中的任何时区,我们就会知道夏时制是否存在。
我怎样才能实现类似的功能?当前,我有一个类似于Windows下拉列表中的值列表。
我理解TimeZone对象将解决这个问题,因为它有一个boolean属性来说明是否存在夏时制。但是,对于如何使用可用的值列表创建TimeZone对象,我非常困惑。
我有如下所示的下拉值:
有了上面的示例值,我如何创建TimeZone对象?
发布于 2018-02-16 11:29:35
这是一项艰巨的任务。在this link中,在“时区数据库”部分,您将看到Windows名称与Iana/Olson数据库中的名称非常不同(后者是Java使用的)。
在Java中,您可以使用TimeZone.getAvailableIDs()或ZoneId.getAvailableZoneIds() (如果您有Java 8 )来查看所有可用的名称,并查看它们如何与Windows列表不匹配。
我认为,你能做的最好的就是将每个Windows名称映射到一个有效的Iana名称上,因为它并不是所有情况下的完美匹配:Iana数据库更完整、更准确,特别是对于夏令数据(包括历史数据),而且更新的频率也比Windows高。
而且名字也有很大的不同,Iana更全面,有更多的名字--一个Windows时区名称可以引用Iana中的多个。我不确定是否有一种简单的方法可以把所有的名字从一个映射到另一个。
但一旦你有了这些名字,就很容易查到:
TimeZone zone = TimeZone.getTimeZone("America/New_York");
// check if it has DST now or in the future (doesn't check the past)
boolean hasDST = zone.observesDaylightTime();
// check if a specific date is in DST
Date someDate = // some java.util.Date
boolean dateInDST = zone.inDaylightTime(someDate);在Java 8中:
ZoneRules rules = ZoneId.of("America/New_York").getRules();
// if it has DST, isFixed is false
boolean isFixed = rules.isFixedOffset();
// if lists are empty, offset never varies, so there's no DST
List<ZoneOffsetTransitionRule> transitionRules = rules.getTransitionRules();
List<ZoneOffsetTransition> transitions = rules.getTransitions();
// check a specific date (using java.time.Instant)
rules.isDaylightSavings(Instant.now());
// check a specific date (using java.util.Date)
Date date = new Date();
rules.isDaylightSavings(date.toInstant());请注意,偏移量的更改并不一定意味着DST。这可能只是一个简单的改变:政府决定“永久地”改变国家的抵消--这意味着“直到其他政治家决定再次改变它”。
日光节约只是偏移量变化的一个特殊情况,因此无法知道这种变化是否与DST相关--比如当一个国家决定更改某些偏移量而不使用DST时;该区域仍将是非固定的(isFixedOffset返回true),因为偏移量发生了变化。
在这种情况下,当发生这些更改时,您可以使用转换列表来了解:
rules.getTransitions().forEach(t -> {
// UTC instant that the change happens
Instant instant = t.getInstant();
// local date and time before the change
LocalDateTime before = t.getDateTimeBefore();
// local date and time after the change
LocalDateTime after = t.getDateTimeAfter();
});这样,您就可以知道抵消更改的确切日期。有些时区没有转换,但是它们有转换规则(比如"DST在11月的第一个星期日开始“)。在这种情况下,可以使用“过渡规则”列表:
rules.getTransitionRules().forEach(r -> {
// check the rule for a specific year
ZoneOffsetTransition t = r.createTransition(2018);
// UTC instant that the change happens
Instant instant = t.getInstant();
// local date and time before the change
LocalDateTime before = t.getDateTimeBefore();
// local date and time after the change
LocalDateTime after = t.getDateTimeAfter();
});发布于 2018-02-16 06:34:03
您可以按照对您的问题的注释中的建议,尝试使用TimeZone。
String zone = "(UTC-12:00) International Date Line West";
String zoneID = "GMT";
zoneID = zoneID + zone.substring(zone.indexOf("-"), zone.indexOf(")"));
System.out.println(zoneID);
TimeZone timeZone = TimeZone.getTimeZone(zoneID);
boolean answer = timeZone.observesDaylightTime();
System.out.print(answer);您可以尝试使用数组列表来迭代所有的值,而不是像我一样使用字符串。时区接受格式的区域ID,如https://docs.oracle.com/javase/7/docs/api/java/util/TimeZone.html所示
更新
UTC不使用DST(源:Time),因此您必须将UTC转换为目标时区,或者使用像zoneID =“America/New”这样的城市名称。更新代码:
ZoneId zd = ZoneId.of(zoneID);
System.out.println(zd.getId());
ZonedDateTime zdt = ZonedDateTime.of(
LocalDateTime.of(LocalDate.of(2018, 4, 12), LocalTime.of(11, 30)), zd);
Instant instant = zdt.toInstant();
ZoneRules zr = zd.getRules();
System.out.println(zr.isDaylightSavings(instant));上面的代码使用java 8时间类。此外,我在4月份使用了LocalDate,因为在大多数观察到DST的国家,它在3月份的某个地方得到了应用。
https://stackoverflow.com/questions/48820340
复制相似问题