为什么在使用 SimpleTimeZone 时 java 的 SimpleDateFormat 从我的 UTC 日期减去 1 秒
Why is java's SimpleDateFormat substracting 1 second from my UTC date when using SimpleTimeZone
有人可以解释为什么在使用 SimpleTimeZone 设置时区时 SimpleDateFormat 会在我解析的日期上减去 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
}
}
SimpleTimeZone.UTC_TIME
的值实际上是2,所以SimpleTimeZone
是用两毫秒的偏移构造的:
/**
* 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;
}
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
您没有正确使用构造函数。
SimpleTimeZone
的构造函数定义为:
public SimpleTimeZone(int rawOffset,
String ID)
Constructs a SimpleTimeZone with the given base time zone offset from GMT and time zone ID with no daylight
saving time schedule.
Parameters:
rawOffset
- The base time zone
offset in milliseconds to GMT.
ID
- The time zone name that is given
to this instance.
因此构造函数的第一个参数是您要创建的时区与 GMT 的时区差异,以毫秒为单位。
这里没有理由使用任何常量 STANDARD_TIME
、UTC_TIME
或 WALL_TIME
。这不是使用它们的地方。但是,因为这些常量是 int
类型,并且 rawOffset
参数是 int
类型,所以 Java 不会阻止您将这些常量错误地传递给构造函数。
在Java源代码中,这个常量定义为:
public static final int UTC_TIME = 2;
所以当你打电话时你实际上在做什么
new SimpleTimeZone(SimpleTimeZone.UTC_TIME, "UTC")
说的是"Please create a time zone which is 2 milliseconds away from GMT, and call it 'UTC'"。我很确定这不是您想要实现的目标。这是一个自定义时区,与 UTC
略有不同,此差异在输出中四舍五入为整秒。
有人可以解释为什么在使用 SimpleTimeZone 设置时区时 SimpleDateFormat 会在我解析的日期上减去 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
}
}
SimpleTimeZone.UTC_TIME
的值实际上是2,所以SimpleTimeZone
是用两毫秒的偏移构造的:
/**
* 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;
}
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
您没有正确使用构造函数。
SimpleTimeZone
的构造函数定义为:
public SimpleTimeZone(int rawOffset, String ID)
Constructs a SimpleTimeZone with the given base time zone offset from GMT and time zone ID with no daylight saving time schedule.
Parameters:
rawOffset
- The base time zone offset in milliseconds to GMT.
ID
- The time zone name that is given to this instance.
因此构造函数的第一个参数是您要创建的时区与 GMT 的时区差异,以毫秒为单位。
这里没有理由使用任何常量 STANDARD_TIME
、UTC_TIME
或 WALL_TIME
。这不是使用它们的地方。但是,因为这些常量是 int
类型,并且 rawOffset
参数是 int
类型,所以 Java 不会阻止您将这些常量错误地传递给构造函数。
在Java源代码中,这个常量定义为:
public static final int UTC_TIME = 2;
所以当你打电话时你实际上在做什么
new SimpleTimeZone(SimpleTimeZone.UTC_TIME, "UTC")
说的是"Please create a time zone which is 2 milliseconds away from GMT, and call it 'UTC'"。我很确定这不是您想要实现的目标。这是一个自定义时区,与 UTC
略有不同,此差异在输出中四舍五入为整秒。