返回给定日期的 BST/GMT
Posted
技术标签:
【中文标题】返回给定日期的 BST/GMT【英文标题】:Return BST/GMT for a given date 【发布时间】:2015-01-08 04:22:43 【问题描述】:在 Java 中,确定特定语言环境的任何给定 Date 对象的夏令时的公认方法是什么。
例如,如果您有两个日期对象
Date date = new Date("01/01/2014");
Date date2 = new Date("01/07/2014");
区域设置为“欧洲/伦敦”,“日期”应返回 GMT,日期 2 应返回“BST”
String timeZone = new String("Europe/London");
TimeZone tz = TimeZone.getTimeZone(timeZone);
System.out.println(tz.getDisplayName(tz.inDaylightTime(date),
TimeZone.SHORT));
TimeZone tz2 = TimeZone.getTimeZone(timeZone);
System.out.println(tz2.getDisplayName(tz2.inDaylightTime(date2),
TimeZone.SHORT));
这两个例子都打印 GMT,第二个不应该打印 BST 吗?
【问题讨论】:
Europe/London
不是Locale,它是proper time zone name。避免使用 3 或 4 个字母的缩写,因为它们既不标准化也不独特。 UTC除外。
【参考方案1】:
java.time
旧的日期时间 API(java.util
日期时间类型及其格式类型,SimpleDateFormat
)已过时且容易出错。建议完全停止使用,改用java.time
,modern date-time API*。
区域设置为“欧洲/伦敦”,“日期”应返回 GMT 和 date2 应该返回“BST”
请注意,Europe/London
是时区 (ZoneId
),而不是 Locale
。 Java SE 8 日期时间 API (java.time
) 为我们提供了 ZonedDateTime
,它会根据 DST 转换自动调整时区偏移量。
演示:
import java.time.LocalDate;
import java.time.ZoneId;
import java.time.ZonedDateTime;
import java.time.format.DateTimeFormatter;
import java.util.Locale;
public class Main
public static void main(String[] args)
DateTimeFormatter dtfInput = DateTimeFormatter.ofPattern("d/M/u", Locale.ENGLISH);
LocalDate date = LocalDate.parse("01/01/2014", dtfInput);
LocalDate date2 = LocalDate.parse("01/07/2014", dtfInput);
ZoneId zoneId = ZoneId.of("Europe/London");
ZonedDateTime zdt = date.atStartOfDay(zoneId);
ZonedDateTime zdt2 = date2.atStartOfDay(zoneId);
DateTimeFormatter dtfOutput = DateTimeFormatter.ofPattern("dd/MM/uuuu'['z']'", Locale.ENGLISH);
System.out.println(zdt.format(dtfOutput));
System.out.println(zdt2.format(dtfOutput));
输出:
01/01/2014[GMT]
01/07/2014[BST]
从Trail: Date Time了解更多关于java.time
,modern date-time API*。
* 出于任何原因,如果您必须坚持使用 Java 6 或 Java 7,您可以使用 ThreeTen-Backport,它将大部分 java.time 功能向后移植到 Java 6 和 7 . 如果您正在为一个 android 项目工作并且您的 Android API 级别仍然不符合 Java-8,请检查 Java 8+ APIs available through desugaring 和 How to use ThreeTenABP in Android Project。
【讨论】:
【参考方案2】:我认为您的日期都不是夏令时,模式是 mm/dd/yyyy,所以您的日期是 2014 年 1 月 1 日和 2014 年 1 月 7 日。 顺便说一句:您使用的构造函数已弃用!
Date date = new Date("01/01/2014");
Date date2 = new Date("01/07/2014");
Date date3 = new Date("07/07/2014");
Calendar cal = Calendar.getInstance(Locale.UK);
cal.setTime(date);
System.out.println(date + " " + cal.getTimeZone().inDaylightTime(date));
cal.setTime(date2);
System.out.println(date2 + " " + cal.getTimeZone().inDaylightTime(date2));
cal.setTime(date3);
System.out.println(date3 + " " + cal.getTimeZone().inDaylightTime(date3));
这应该会给你一个提示。至少你知道日期是否在夏令时,如何调用这个时间是第二个问题,我认为它不能用标准 API 解决。你试过看http://www.joda.org/joda-time/吗?它是一个用于日期时间计算的 API。
【讨论】:
String 格式有 Data 构造函数吗?不推荐使用的是 int 年、月、日格式。 这里有 SimpleDateFormat:SimpleDateFormat sdf = new SimpleDateFormat("dd.MM.yyyy"); Date date = sdf.parse("01.01.2014"); Date date2 = sdf.parse("07.01.2014"); Date date3 = sdf.parse("01.07.2014");
。 API 文档和模式:docs.oracle.com/javase/7/docs/api/java/text/…
啊,该死的美国日期格式!这实际上是正确的,愚蠢的错误。
但是我的意思是Date对象本身的构造函数,而不是SimpleDateFormat的parse方法的参数
docs.oracle.com/javase/7/docs/api/java/util/Date.html 这里是日期的API。只有未弃用的构造函数是 Date()
和 Date(long date)
,其中 long date
是 number of milliseconds since the standard base time known as "the epoch", namely January 1, 1970, 00:00:00 GMT.
所以:不,您不能直接从字符串构造日期对象。以上是关于返回给定日期的 BST/GMT的主要内容,如果未能解决你的问题,请参考以下文章