一个国家的时区,是否实行夏令时
Time zone of a country, whether day light savings is in effect
考虑以下代码:
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
。但是我需要确定我是否应该 return AST
或 ADT
.
我需要确定 AST
现在是否处于夏令时。如果是夏令时,我可以 return ADT
,如果不是,我可以 return AST
。但我不知道如何确定该时区是否处于夏令时。
有人可以帮我吗?
解决这个问题:
对于任何特定时区
TimeZone tz = TimeZone.getTimeZone("EST");
boolean inDs = tz.inDaylightTime(new Date());
您可以使用此程序来确定该时区是否处于夏令时。
另请参阅此 link。
TimeZone.getTimeZone("CST") returns GMT
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() ));
}
}
首先,避免使用时区名称的缩写(如 CST
、PST
或 CEST
),因为它们是 ambiguous and not standard.
CST
,例如,被more than one timezone: it can be "Central Standard Time", "China Standard Time" or "Cuba Standard Time”使用。而且每个人对夏令时都有不同的规定,所以使用缩写不一定能得到你期望的结果。
TimeZone
class 假定这些短名称的一些默认值(所有任意选择,任何默认值都是如此)并且还具有 returning GMT when the name is unknown.[=51= 的奇怪行为]
为避免这些歧义,最好使用 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
(因为今天是 2017 年 9 月 13 日,纽约正处于夏令时和abbreviation used is EDT)。
在这种情况下,您可以创建格式化程序,并使用您的 if
逻辑在其中设置正确的时区。然后,格式化程序负责检查日期是否为夏令时,并返回正确的缩写。
Java新Date/TimeAPI
旧的 classes(Date
、Calendar
和 SimpleDateFormat
)有 lots of problems and design issues,它们正在被新的 APIs.
如果您正在使用 Java 8,请考虑使用 new java.time API. It's easier, less bugged and less error-prone than the old APIs.
如果您使用 Java <= 7,您可以使用 ThreeTen Backport, a great backport for Java 8's new date/time classes. And for Android, you'll also need the ThreeTenABP (more on how to use it ).
下面的代码适用于两者。
唯一的区别是包名称(在 Java 8 中是 java.time
,在 ThreeTen Backport(或 Android 的 ThreeTenABP)中是 org.threeten.bp
),但是 classes 和方法 names 相同。
首先,我使用 z
模式(对应于区域短名称)和英语语言环境创建了一个 DateTimeFormatter
。
然后我用一个ZonedDateTime
,代表一个特定时区的日期和时间,用now()
方法得到当前的date/time。我还使用 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 不像旧的那么宽松。
当区域不存在时,TimeZone
假定许多任意默认值和 returns“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)));
考虑以下代码:
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
。但是我需要确定我是否应该 return AST
或 ADT
.
我需要确定 AST
现在是否处于夏令时。如果是夏令时,我可以 return ADT
,如果不是,我可以 return AST
。但我不知道如何确定该时区是否处于夏令时。
有人可以帮我吗?
解决这个问题:
对于任何特定时区
TimeZone tz = TimeZone.getTimeZone("EST");
boolean inDs = tz.inDaylightTime(new Date());
您可以使用此程序来确定该时区是否处于夏令时。
另请参阅此 link。
TimeZone.getTimeZone("CST") returns GMT
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() ));
}
}
首先,避免使用时区名称的缩写(如 CST
、PST
或 CEST
),因为它们是 ambiguous and not standard.
CST
,例如,被more than one timezone: it can be "Central Standard Time", "China Standard Time" or "Cuba Standard Time”使用。而且每个人对夏令时都有不同的规定,所以使用缩写不一定能得到你期望的结果。
TimeZone
class 假定这些短名称的一些默认值(所有任意选择,任何默认值都是如此)并且还具有 returning GMT when the name is unknown.[=51= 的奇怪行为]
为避免这些歧义,最好使用 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
(因为今天是 2017 年 9 月 13 日,纽约正处于夏令时和abbreviation used is EDT)。
在这种情况下,您可以创建格式化程序,并使用您的 if
逻辑在其中设置正确的时区。然后,格式化程序负责检查日期是否为夏令时,并返回正确的缩写。
Java新Date/TimeAPI
旧的 classes(Date
、Calendar
和 SimpleDateFormat
)有 lots of problems and design issues,它们正在被新的 APIs.
如果您正在使用 Java 8,请考虑使用 new java.time API. It's easier, less bugged and less error-prone than the old APIs.
如果您使用 Java <= 7,您可以使用 ThreeTen Backport, a great backport for Java 8's new date/time classes. And for Android, you'll also need the ThreeTenABP (more on how to use it
下面的代码适用于两者。
唯一的区别是包名称(在 Java 8 中是 java.time
,在 ThreeTen Backport(或 Android 的 ThreeTenABP)中是 org.threeten.bp
),但是 classes 和方法 names 相同。
首先,我使用 z
模式(对应于区域短名称)和英语语言环境创建了一个 DateTimeFormatter
。
然后我用一个ZonedDateTime
,代表一个特定时区的日期和时间,用now()
方法得到当前的date/time。我还使用 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 不像旧的那么宽松。
TimeZone
假定许多任意默认值和 returns“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)));