无法将字符串转换为 Java 中的日期,转换后时区错误
Can't convert string to date in Java, wrong timezone after conversion
我有一个包含日期的 Strings
数组,例如:
- 2016 年 2 月 9 日星期二14:07:00格林威治标准时间;
- 2016 年 2 月 9 日星期二19:55:00格林威治标准时间。
现在我想在此列表中查找最近的日期。为此,我尝试将这些字符串反序列化为 java.util.Date
对象,然后比较它们。
java.util.Date
对象生成代码示例:
strDate = "Tue, 09 Feb 2016 14:07:00 GMT";
DateFormat format = new SimpleDateFormat("EEE, dd MMM yyyy HH:mm:ss z");
Date date;
try {
date = format.parse(strDate);
//Result: Tue Feb 09 16:07:00 IST 2016
System.out.println("Result: " + date.toString());
} catch(ParseException e) {
e.printStackTrace();
}
我的问题:
- 为什么结果是 IST 2016 时区而不是 GMT? IST 2016 代表什么?是印度标准时间还是爱尔兰标准时间还是以色列标准时间?
- 初始字符串是
EEE, dd MMM
格式,SimpleDateFormat
模式也是这种格式,所以为什么结果是EEE, MMM dd
格式?
- 如何获得与初始字符串处于同一时区的
java.util.Date
对象,在我的例子中 — GMT?
- 我用来在列表中查找最近日期的方法是否可行,或者在 Java 8 中有更多 convenient/modern 方法可以做到这一点,例如,使用
LocalDateTime
?
您依赖 Date.toString()
来打印您的日期,而您应该使用格式化程序将其格式化为 String
。您看到的只是 Date.toString()
的默认模式。您必须记住的是 Date
没有时区。您正在看到带有 IST 时区的输出,这一定是因为 JVM 的当前语言环境设置为时区名称为 "IST"
.
的某个特定语言环境
关于你的第 4 点,是的,你可以使用 Java 8 中介绍的 Java 时间 API 来做得更干净。你可以创建一个 List
要解析的字符串,创建一个 DateTimeFormatter
来解析它,并保留最大日期值。
public static void main(String[] args) {
List<String> dates = Arrays.asList("Tue, 09 Feb 2016 14:07:00 GMT", "Tue, 09 Feb 2016 19:55:00 GMT");
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("EEE, dd MMM yyyy HH:mm:ss z", Locale.ENGLISH);
ZonedDateTime maxDate = dates.stream()
.map(s -> ZonedDateTime.parse(s, formatter))
.max(ZonedDateTime::compareTo)
.get(); // or .orElse(null)
System.out.println(maxDate);
}
此代码使用 ZonedDateTime
来保持传入字符串的时区。
您的计算机似乎设置为 IST
。要强制 GMT
输出,请导入 java.util.TimeZone
并在您的 try
块中执行此操作:
format.setTimeZone(TimeZone.getTimeZone("GMT"));
date = format.parse(strDate);
System.out.println("Result: " + format.format(date));
我有一个包含日期的 Strings
数组,例如:
- 2016 年 2 月 9 日星期二14:07:00格林威治标准时间;
- 2016 年 2 月 9 日星期二19:55:00格林威治标准时间。
现在我想在此列表中查找最近的日期。为此,我尝试将这些字符串反序列化为 java.util.Date
对象,然后比较它们。
java.util.Date
对象生成代码示例:
strDate = "Tue, 09 Feb 2016 14:07:00 GMT";
DateFormat format = new SimpleDateFormat("EEE, dd MMM yyyy HH:mm:ss z");
Date date;
try {
date = format.parse(strDate);
//Result: Tue Feb 09 16:07:00 IST 2016
System.out.println("Result: " + date.toString());
} catch(ParseException e) {
e.printStackTrace();
}
我的问题:
- 为什么结果是 IST 2016 时区而不是 GMT? IST 2016 代表什么?是印度标准时间还是爱尔兰标准时间还是以色列标准时间?
- 初始字符串是
EEE, dd MMM
格式,SimpleDateFormat
模式也是这种格式,所以为什么结果是EEE, MMM dd
格式? - 如何获得与初始字符串处于同一时区的
java.util.Date
对象,在我的例子中 — GMT? - 我用来在列表中查找最近日期的方法是否可行,或者在 Java 8 中有更多 convenient/modern 方法可以做到这一点,例如,使用
LocalDateTime
?
您依赖 Date.toString()
来打印您的日期,而您应该使用格式化程序将其格式化为 String
。您看到的只是 Date.toString()
的默认模式。您必须记住的是 Date
没有时区。您正在看到带有 IST 时区的输出,这一定是因为 JVM 的当前语言环境设置为时区名称为 "IST"
.
关于你的第 4 点,是的,你可以使用 Java 8 中介绍的 Java 时间 API 来做得更干净。你可以创建一个 List
要解析的字符串,创建一个 DateTimeFormatter
来解析它,并保留最大日期值。
public static void main(String[] args) {
List<String> dates = Arrays.asList("Tue, 09 Feb 2016 14:07:00 GMT", "Tue, 09 Feb 2016 19:55:00 GMT");
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("EEE, dd MMM yyyy HH:mm:ss z", Locale.ENGLISH);
ZonedDateTime maxDate = dates.stream()
.map(s -> ZonedDateTime.parse(s, formatter))
.max(ZonedDateTime::compareTo)
.get(); // or .orElse(null)
System.out.println(maxDate);
}
此代码使用 ZonedDateTime
来保持传入字符串的时区。
您的计算机似乎设置为 IST
。要强制 GMT
输出,请导入 java.util.TimeZone
并在您的 try
块中执行此操作:
format.setTimeZone(TimeZone.getTimeZone("GMT"));
date = format.parse(strDate);
System.out.println("Result: " + format.format(date));