为什么java的SimpleDateFormat在使用SimpleTimeZone时从我的UTC日期减去1秒

时间:2015-01-23 10:33:10

标签: java simpledateformat

有人可以解释为什么SimpleDateFormat在使用SimpleTimeZone设置时区时将我的解析日期减去1秒?

这是一个jdk错误吗?

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.SimpleTimeZone;
import java.util.TimeZone;

public class SimpleDateFormatTest {

    public static void main(String[] args) throws ParseException {

        SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss'Z'");

        format.setTimeZone(TimeZone.getTimeZone("UTC"));
        System.out.println(format.parse("2016-02-24T17:31:00Z")); 
        // prints Wed Feb 24 17:31:00 UTC 2016

        format.setTimeZone(new SimpleTimeZone(SimpleTimeZone.UTC_TIME, "UTC"));
        System.out.println(format.parse("2016-02-24T17:31:00Z")); 
        // Wed Feb 24 17:30:59 UTC 2016
    }

}

2 个答案:

答案 0 :(得分:5)

您未正确使用构造函数。

SimpleTimeZone的构造函数定义为:

  

public SimpleTimeZone(int rawOffset, String ID)

     

构造一个SimpleTimeZone,其中给定的基准时区偏离GMT,时区ID没有日光   节省时间表。

     

<强>参数:

     

rawOffset - 基准时区   以GMT为单位的偏移量。

     

ID - 给出的时区名称   对于这个例子。

因此,构造函数的第一个参数是您创建的时区与GMT的差异,以毫秒为单位。

此处没有理由使用任何常量STANDARD_TIMEUTC_TIMEWALL_TIME。这不是他们使用的地方。但是,因为这些常量的类型为int,而rawOffset参数的类型为int,所以Java不会阻止您将这些常量错误地传递给构造函数。

在Java源代码中,此常量定义为:

public static final int UTC_TIME = 2;

那么你打电话时实际上在做什么

new SimpleTimeZone(SimpleTimeZone.UTC_TIME, "UTC")

说&#34;请创建一个距GMT 2毫秒的时区,并将其称为&#39; UTC&#39;&#34;。我很确定这不是你想要达到的目标。这是一个自定义时区,与UTC略有不同,这个差异在您的输出中四舍五入到整秒。

答案 1 :(得分:3)

SimpleTimeZone.UTC_TIME的值实际为2,因此SimpleTimeZone的构造偏移为2毫秒:

/**
 * Constant for a mode of start or end time specified as UTC. European
 * Union rules are specified as UTC time, for example.
 * @since 1.4
 */
public static final int UTC_TIME = 2;

/**
 * Constructs a SimpleTimeZone with the given base time zone offset from GMT
 * and time zone ID with no daylight saving time schedule.
 *
 * @param rawOffset  The base time zone offset in milliseconds to GMT.
 * @param ID         The time zone name that is given to this instance.
 */
public SimpleTimeZone(int rawOffset, String ID)
{
    this.rawOffset = rawOffset;
    setID (ID);
    dstSavings = millisPerHour;
}

Ideone test

public static void main(String[] args) throws ParseException {
    SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss'Z'");

    format.setTimeZone(TimeZone.getTimeZone("UTC"));
    Date date1 = format.parse("2016-02-24T17:31:00Z");
    System.out.println(date1.getTime());

    format.setTimeZone(new SimpleTimeZone(SimpleTimeZone.UTC_TIME, "UTC"));
    Date date2 = format.parse("2016-02-24T17:31:00Z");
    System.out.println(date2.getTime());
}

结果:

1456335060000
1456335059998