public static void main(String[] args) {
String opDate = "Tue Jan 03 00:00:00 MSK 2006";
String date = convertDate(opDate, "yyyyMMdd");
System.out.println("opDate: " + opDate);
System.out.println("date: " + date);
}
public static String convertDate(String opDate, String dateFormat) {
Date date = new Date();
// Mon Jan 02 00:00:00 MSK 2006
SimpleDateFormat dateParser = new SimpleDateFormat("EEE MMM dd HH:mm:ss zzz yyyy", Locale.US);
try {
date = dateParser.parse(opDate);
} catch (Exception e) {
System.out.println("exception = " + e.toString());
}
SimpleDateFormat df = new SimpleDateFormat(dateFormat);
df.setTimeZone(TimeZone.getTimeZone("Russia/Moscow"));
String strDate = df.format( date.getTime() );
return strDate.trim();
}
出:
opDate:Tue Jan 03 00:00:00 MSK 2006
日期:20060102
为什么会在1月02日返回?
答案 0 :(得分:8)
问题是获取"Russia/Moscow"
时区。正确的zoneinfo ID为"Europe/Moscow"
。更改ID,问题消失了:
df.setTimeZone(TimeZone.getTimeZone("Europe/Moscow"));
遗憾的是,TimeZone.getTimeZone("random rubbish")
返回UTC时区,而不是以某种方式告诉您它已被破坏。
答案 1 :(得分:5)
可能由于时区转换。 我建议你也打印结果日期的时间和时区。这可能是1月2日,23:00或其他什么。
这是因为您在SimpleDataFormat
上设置了不同的时区。
答案 2 :(得分:3)
时区。
您指定1月3日午夜在MSK中。这是格林尼治标准时间1月2日晚上9点(可能的默认时区)。
我可以看到您在莫斯科时间也尝试输出,但Russia/Moscow
不是有效的时区,getTimeZone
来电"有帮助" silently defaults to returning GMT。这当然不会在格式化时更改日期的时区,并将其输出为1月2日。
如果您将时区设置为Europe/Moscow
,您将获得预期的输出。
答案 3 :(得分:2)
是否与您在两个不同的时区之间转换日期有关?
答案 4 :(得分:1)
如果你换行:
String date = convertDate(opDate, "yyyyMMdd");
为:
String date = convertDate(opDate, "EEE MMM dd HH:mm:ss zzz yyyy");
你可以看到程序的输出:
opDate: Tue Jan 03 00:00:00 MSK 2006
date: Mon Jan 02 20:00:00 GMT 2006
你的TimeZone设置不好:
df.setTimeZone(TimeZone.getTimeZone("Russia/Moscow"));
你需要:
df.setTimeZone(TimeZone.getTimeZone("Europe/Moscow"));
最后夏天延迟1小时。
答案 5 :(得分:1)
time_resource_id, time_date t1 , t2 , t3
-------------------------------------------------------------------
123 2021-06-19 8:00 10:00 13:00
日期时间 API 及其格式化 API java.util
已过时且容易出错。建议完全停止使用它们并切换到 modern Date-Time API*。
使用 SimpleDateFormat
(现代日期时间 API)的解决方案:
java.time
输出:
import java.time.ZonedDateTime;
import java.time.format.DateTimeFormatter;
import java.util.Locale;
public class Main {
public static void main(String[] args) {
String strDateTime = "Tue Jan 03 00:00:00 MSK 2006";
String formatted = formatDateTimeStringTo(strDateTime, "yyyyMMdd", Locale.ENGLISH);
System.out.println("opDate: " + strDateTime);
System.out.println("date: " + formatted);
}
public static String formatDateTimeStringTo(String strDateTime, String targetFormat, Locale locale) {
DateTimeFormatter parser = DateTimeFormatter.ofPattern("EEE MMM d H:m:s zzz u", locale);
DateTimeFormatter formatter = DateTimeFormatter.ofPattern(targetFormat, locale);
ZonedDateTime zdt = ZonedDateTime.parse(strDateTime, parser);
// System.out.println(zdt); // 2006-01-03T00:00+03:00[Europe/Moscow]
return zdt.format(formatter);
}
}
从 Trail: Date Time 了解有关现代 Date-Time API 的更多信息。
请您的发布商切换到时区的标准命名约定。 standard naming convention 是地区/城市,例如欧洲/莫斯科。时区的二/三/四字母缩写容易出错,如 Timezone
documentation 页面中的以下文本所述:
为了与 JDK 1.1.x 兼容,其他一些三字母时区 还支持 ID(例如“PST”、“CTT”、“AST”)。然而,他们的 不推荐使用因为相同的缩写经常用于 多个时区(例如,“CST”可以是美国的“Central 标准时间”和“中国标准时间”),Java平台可以 然后只识别其中一个。
* 出于任何原因,如果您必须坚持使用 Java 6 或 Java 7,您可以使用 ThreeTen-Backport,它将大部分 java.time 功能向后移植到 Java 6 & 7. 如果您正在为 Android 项目工作并且您的 Android API 级别仍然不符合 Java-8,请检查 Java 8+ APIs available through desugaring 和 How to use ThreeTenABP in Android Project。