返回给定日期的 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 datenumber of milliseconds since the standard base time known as "the epoch", namely January 1, 1970, 00:00:00 GMT. 所以:不,您不能直接从字符串构造日期对象。

以上是关于返回给定日期的 BST/GMT的主要内容,如果未能解决你的问题,请参考以下文章

strtotime 可以在给定日期之后返回一天中的日期和时间吗?

在ACCESS中返回给定日期星期几的植的函数

python 给定日期 返回属于当年第几周

使用给定的参考年份计算给定日期的周数

在javascript中检查给定的日期格式

如何在sql中获取两个给定日期之间的日期