Java Date,使用特定日光模式渲染

时间:2009-11-19 01:28:38

标签: java datetime date timezone dst

我有一个Java Date,它来自夏令时的夏令时。例如:

  

2009年6月1日太平洋时间上午06:00

我的问题是,如何将此日期显示为我的本地时区和当前夏令时模式(在我的情况下是太平洋标准时间)?

  

2009年6月1日05:00太平洋标准时间

Java Date.toString()SimpleDateFormat原始夏令时模式显示日期。例如:

System.out.println(new Date(1243861200000L));

输出:

  

Mon Jun 01 06:00:00 PDT 2009

DateFormat dateFormat = new SimpleDateFormat("MMM dd, yyyy hh:mm aa zzz");
dateFormat.setTimeZone(TimeZone.getTimeZone("PST"));
System.out.println(dateFormat.format(new Date(1243861200000L)));

输出:

  

2009年6月1日太平洋时间上午06:00

我真正想看的是太平洋标准时间凌晨5点(相当于太平洋夏令时上午6点)。有没有办法强迫它使用另一种夏令时模式?

跟进:顺便说一下,这是Windows XP的行为。 6月1日上午6点创建的文件(由资源管理器,命令提示符等)将在6月1日,冬季凌晨5点出现。

4 个答案:

答案 0 :(得分:2)

我认为没有办法强制DateFormatTimeZone格式应用于不存在的时间。 PST仅适用于冬季,PDT仅在夏季使用。

我使用TimeZone返回的所有TimeZone.getAvailableIDs()格式化了这个日期,并找到了两个在特定时间返回PST的地方:Pacific / Pitcairn和SystemV / PST8。您可以尝试使用其中一个,但我不知道其他规则适用于哪个时区对象。

如果您只关心获得该偏移的时间,可以使用GMT-8作为您的TimeZone。但是,该字符串将显示在格式化的日期字符串中,而不是PST。

更新:这是一种采用任何时区并让它忽略所有夏令时规则的方法。您可以抓取TimeZone对象,然后抓取另一个TimeZone.getTimeZone()对象。在第二个对象上,将IdrawOffset设置为第一个TimeZone中的相应对象。

例如:

    DateFormat dateFormat = new SimpleDateFormat("MMM dd, yyyy hh:mm aa zzz");
    TimeZone defaultTimeZone = TimeZone.getDefault();
    TimeZone timeZone = TimeZone.getTimeZone("");
    timeZone.setID(defaultTimeZone.getID());
    timeZone.setRawOffset(defaultTimeZone.getRawOffset());
    dateFormat.setTimeZone(timeZone);
    System.out.println(dateFormat.format(new Date(1243861200000L)));

这将打印出您正在寻找的内容。

答案 1 :(得分:2)

PST / PDT全年变化。 Java尝试确定哪一个在给定日期有效。随着法律和地区的变化,这一事情显然会发生变化你能用绝对时区吗?指定GMT的偏差将在同一年左右。

    DateFormat dateFormat = new SimpleDateFormat("MMM dd, yyyy hh:mm aa zzz");
    dateFormat.setTimeZone(TimeZone.getTimeZone("GMT-07:00"));
    System.out.println(dateFormat.format(new Date(1243861200000L)));

Jun 01, 2009 06:00 AM GMT-07:00

答案 2 :(得分:1)

这可能会成功:

    /*
     * Create a date that represents 1,243,861,200,000 milliseconds since
     * Jan 1, 1970
     */
    Date date = new Date(1243861200000L);

    /*
     * Print out the date using the current system's default format and time
     * zone. In other words, this will print differently if you set the
     * operating zone's time zone differently.
     */
    System.out.println(date);

    /*
     * Specify the format and timezone to use
     */
    DateFormat dateFormat = new SimpleDateFormat(
            "MMM dd, yyyy hh:mm aa zzz");
    TimeZone pstTZ = TimeZone.getTimeZone("PST");
    dateFormat.setTimeZone(pstTZ);
    System.out.println(dateFormat.format(date));

    /*
     * It looks like what you want is to actually display a different date
     * (different # milliseconds since epoch) in the summer months. To do that, you
     * need to change the date by subtracting an hour.
     */
    if(pstTZ.inDaylightTime(date)){
        Calendar cal = Calendar.getInstance();
        cal.setTime(date);
        cal.add(Calendar.HOUR, -1);
        date = cal.getTime();
    }
    //now this should always print "5:00". However, it will show as 5:00 PDT in summer and 5:00 PST in the winter which are actually 2 different dates. So, I think you might need to think about exactly what it is you're trying to achieve. 
    System.out.println(dateFormat.format(date));

答案 3 :(得分:0)

DateFormat dateFormat = new SimpleDateFormat("MMM dd, yyyy hh:mm aa zzz"); 
dateFormat.setTimeZone(TimeZone.getTimeZone("Pacific/Pitcairn")); 
System.out.println(dateFormat.format(new Date(1243861200000L)));

其他评论:zzz将打印出PST,而z将打印出GMT-08:00。 TimeZone.getTimeZone(“EST”)适用于东部标准时间,让我觉得这是TimeZone.getTimeZone(“PST”)的错误。

我建议使用预定义的时区,因为它们可能令人困惑:

public static final TimeZone ZONE_GREENWICH_MEAN_TIME = TimeZone.getTimeZone("GMT");
public static final TimeZone ZONE_EASTERN_DAYLIGHT_TIME = TimeZone.getTimeZone("America/New_York"); // EDT, GMT-04:00
public static final TimeZone ZONE_EASTERN_STANDARD_TIME = TimeZone.getTimeZone("EST"); // GMT-05:00
public static final TimeZone ZONE_PACIFIC_DAYLIGHT_TIME = TimeZone.getTimeZone("America/Los_Angeles"); // PDT, GTM-0700
public static final TimeZone ZONE_PACIFIC_STANDARD_TIME = TimeZone.getTimeZone("Pacific/Pitcairn"); // PST, GMT-08:00

我遇到了类似问题的另一个时间“2009-11-01 08:44:44”。我尝试迭代所有ID,没有人会打印EDT。有趣的是,“2010-11-01 08:44:44”将打印EDT。从1990年到2010年,只有2007年,2008年和2010年将印刷EDT。当我检查从0到2499的年份时,只有431个EDT,第一个在1940年(这必须是在引入EDT时)。因此在560年(1940-2499)中,只有431个具有打印EDT的ID。从1940年到2006年,只有10年有ID打印EDT。 2006年之后,每4年,5年或10年,有一年不会打印EDT。​​