考虑以下代码:
if(strTimeZoneCd.equals("A"))
locTz = TimeZone.getTimeZone("AST");
else if(strTimeZoneCd.equals("M"))
locTz = TimeZone.getTimeZone("MST");
else if(strTimeZoneCd.equals("P"))
locTz = TimeZone.getTimeZone("PST");
else if(strTimeZoneCd.equals("H"))
locTz = TimeZone.getTimeZone("HST");
else if(strTimeZoneCd.equals("C"))
locTz = TimeZone.getTimeZone("CST");
else if(strTimeZoneCd.equals("E"))
locTz = TimeZone.getTimeZone("EST");
else if(strTimeZoneCd.equals("G"))
locTz = TimeZone.getTimeZone("GMT");
else if(strTimeZoneCd.equals("Y"))
locTz = TimeZone.getTimeZone("AKST");
如果我传递的是A
,它会给我AST
。但是,我需要确定是否应该返回AST
或ADT
。
我需要确定AST
现在是否在夏令时下。如果它在夏令时下,我可以返回ADT
,如果不是,我可以返回AST
。但我不知道如何确定该时区是否在夏令时下。
有人可以帮帮我吗?
答案 0 :(得分:1)
解决这个问题:
对于任何特定的TimeZone
TimeZone tz = TimeZone.getTimeZone("EST");
boolean inDs = tz.inDaylightTime(new Date());
答案 1 :(得分:1)
首先,请避免使用时区名称的简短缩写(例如CST
,PST
或CEST
),因为它们是ambiguous and not standard。
CST
由more than one timezone使用:它可以是“Central Standard Time”,“China Standard Time”或“Cuba Standard Time”。每个人都有关于Dayligh Saving Time的不同规则,因此使用缩写可能不一定能得到您期望的结果。
TimeZone
类假设这些短名称有一些默认值(所有任意选择,如任何默认选项),并且还具有returning GMT when the name is unknown的奇怪行为。
为避免这些含糊不清,最好使用IANA timezones names(始终采用Region/City
格式,例如Asia/Kolkata
或America/New_York
。
您可以致电TimeZone.getAvailableIDs()
获取可用时区列表(并选择最适合您系统的时区)。
然后您可以使用inDaylightTime()
方法,如其他答案中所述。
另一种方法是使用格式化程序,因为它会自动检查是否处于夏令时并打印区域短名称。我还使用java.util.Locale
表示名称应该是英文(我不确定不同语言是否会影响短区名称,这是“以防万一”方法):
// formatter with `z` (zone short name)
SimpleDateFormat sdf = new SimpleDateFormat("z", Locale.ENGLISH);
// set timezone in the formatter
sdf.setTimeZone(TimeZone.getTimeZone("America/New_York"));
// prints the zone name for the current date
System.out.println(sdf.format(new Date()));
上面的代码打印EDT
(因为今天,9月13日 th 2017,纽约处于夏令时和abbreviation used is EDT)。
在这种情况下,您可以创建格式化程序,并使用if
逻辑在其中设置正确的时区。然后,格式化程序负责检查日期是否为夏令时,并返回正确的缩写。
旧类(Date
,Calendar
和SimpleDateFormat
)有lots of problems和design issues,它们将被新API取代。< / p>
如果您使用的是 Java 8 ,请考虑使用new java.time API。它更容易,less bugged and less error-prone than the old APIs。
如果您使用的是 Java&lt; = 7 ,则可以使用ThreeTen Backport,这是Java 8新日期/时间类的绝佳后端。对于 Android ,您还需要ThreeTenABP(更多关于如何使用它here)。
以下代码适用于两者。
唯一的区别是包名称(在Java 8中为java.time
,在ThreeTen Backport(或Android的ThreeTenABP)中为org.threeten.bp
),但类和方法名称是相同的
首先,我使用DateTimeFormatter
模式(对应于区域短名称)和英语区域设置创建z
。
然后我使用ZonedDateTime
表示特定时区的日期和时间,然后使用now()
方法获取当前日期/时间。我还使用ZoneId
来指定我想要的时区:
// create formatter for short zone name and English locale
DateTimeFormatter fmt = DateTimeFormatter.ofPattern("z", Locale.ENGLISH);
// format current date in New York timezone
System.out.println(fmt.format(ZonedDateTime.now(ZoneId.of("America/New_York"))));
这也会打印EDT
。您可以应用上面相同的if
逻辑来定义ZoneId.of()
中将使用的时区。只是提醒不要使用短名称(CST
等),因为新API并不像旧API那么宽松。
TimeZone
会假定大量任意默认值并返回“GMT”,但如果您尝试获取无效区域,则ZoneId
会抛出异常(某些缩写应该适用于复古兼容性的原因,但默认值也是任意的,你应该避免它们。)
您可以选择创建时区名称的自定义地图,因此您无需制作大量if
子句来确定相应的区域。像这样:
// create custom map of zone names
Map<String, String> customZones = new HashMap<>();
// map "E" to New York
customZones.put("E", "America/New_York");
// map "G" to GMT
customZones.put("G", "GMT");
...
// create timezone using the custom map ("E" will create "America/New_York" zone)
ZoneId zone = ZoneId.of("E", customZones);
// format current date in specified timezone
System.out.println(fmt.format(ZonedDateTime.now(zone)));
答案 2 :(得分:0)
您可以使用此程序确定该时区是否在白天节省下。
另见此链接。
import java.util.Date;
import java.util.TimeZone;
public class test {
public static void main(String[] args) {
System.out.println(TimeZone.getTimeZone("EST").inDaylightTime( new Date() ));
System.out.println(TimeZone.getTimeZone( "GMT-9:00").inDaylightTime( new Date() ));
}
}