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

jos*_*res 5 java simpledateformat

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

这是一个jdk bug吗?

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
    }

}
Run Code Online (Sandbox Code Playgroud)

Rea*_*tic 5

你正在使用不正确的构造函数.

构造函数SimpleTimeZone定义为:

public SimpleTimeZone(int rawOffset, String ID)

构造一个SimpleTimeZone,其中给定的基准时区偏离GMT和时区ID,没有夏令时计划.

参数:

rawOffset - 以GMT为单位的基准时区偏移量(以毫秒为单位).

ID - 为此实例指定的时区名称.

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

没有理由使用任何常量STANDARD_TIME,UTC_TIME或者WALL_TIME在这里.这不是他们使用的地方.但是,因为这些常量是类型的int,并且rawOffset参数是类型的int,所以Java不会阻止您将这些常量错误地传递给构造函数.

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

public static final int UTC_TIME = 2;
Run Code Online (Sandbox Code Playgroud)

所以当你打电话时你实际上在做什么

new SimpleTimeZone(SimpleTimeZone.UTC_TIME, "UTC")
Run Code Online (Sandbox Code Playgroud)

是说"请创建一个距离GMT 2毫秒的时区,并称之为'UTC'".我很确定这不是你想要实现的目标.这是一个自定义时区,UTC与您的输出略有不同,这个差异四舍五入到整秒.