【问题标题】:Return BST/GMT for a given date返回给定日期的 BST/GMT
【发布时间】: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除外。

标签: java datetime dst gmt


【解决方案1】:

java.time

旧的日期时间 API(java.util 日期时间类型及其格式类型,SimpleDateFormat)已过时且容易出错。建议完全停止使用,改用java.timemodern 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.timemodern date-time API*


* 出于任何原因,如果您必须坚持使用 Java 6 或 Java 7,您可以使用 ThreeTen-Backport,它将大部分 java.time 功能向后移植到 Java 6 和 7 . 如果您正在为一个 Android 项目工作并且您的 Android API 级别仍然不符合 Java-8,请检查 Java 8+ APIs available through desugaringHow 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. 所以:不,您不能直接从字符串构造日期对象。
    猜你喜欢
    • 2013-02-21
    • 1970-01-01
    • 2011-12-14
    • 2012-02-06
    • 1970-01-01
    • 2015-09-17
    • 1970-01-01
    • 2020-07-15
    • 2013-02-27
    相关资源
    最近更新 更多