You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

SimpleDateFormat与DateFormat时区不一致问题求助

为什么SimpleDateFormat和DateFormat设置德国Locale后时区显示不同?

嘿,我来帮你理清这个问题~你看到的CEST和MESZ其实是同一个时区的不同语言缩写,背后的原因和两个API的行为差异有关:

1. 直接打印Date对象的行为

你的getDateFromStringSimpleDateFormat方法返回的是Date对象,当你用System.out.println输出它时,会调用Date.toString()方法——这个方法是硬编码使用英文的时区名称,完全忽略你设置的Locale.GERMANY。所以它会显示CEST(Central European Summer Time,中欧夏令时的英文缩写)。

2. DateFormat格式化的行为

而getStringNow里的DateFormat是用德国Locale初始化的,它会遵循本地化规则,使用德语的时区缩写MESZ(Mitteleuropäische Sommerzeit,中欧夏令时的德语表达),这才是符合你设置Locale的预期输出。

解决方法:不要直接打印Date,用格式化工具输出

如果你想让解析后的日期也显示德语时区缩写,别直接打印Date对象,而是用DateFormat或SimpleDateFormat再格式化一次。修改你的main方法试试:

public static void main(String[] args) {
    System.out.println(getStringNow());
    Date parsedDate = getDateFromStringSimpleDateFormat("01.05.2018 00:00:00");
    // 用德国Locale的DateFormat格式化解析后的日期
    DateFormat germanFormatter = DateFormat.getDateTimeInstance(dateStyleLoc, timeStyleLoc, localeLoc);
    System.out.println("SimpleDateFormat解析后格式化结果: " + germanFormatter.format(parsedDate));
}

这样输出的时区就会和getStringNow的结果一致,显示MESZ啦。

额外推荐:使用Java 8+的java.time API

旧的DateFormat和SimpleDateFormat不仅线程不安全,还存在不少设计缺陷。Java 8引入的java.time包(比如ZonedDateTime、DateTimeFormatter)更可靠,也更容易处理本地化和时区问题。举个替代的例子:

import java.time.LocalDateTime;
import java.time.ZoneId;
import java.time.ZonedDateTime;
import java.time.format.DateTimeFormatter;
import java.util.Locale;

public class StringAndDateFormat {
    private static final Locale localeLoc = Locale.GERMANY;
    private static final ZoneId GERMAN_ZONE = ZoneId.of("Europe/Berlin");
    private static final DateTimeFormatter OUTPUT_FORMATTER = DateTimeFormatter.ofPattern("dd.MM.yy HH:mm:ss z", localeLoc);
    private static final DateTimeFormatter INPUT_FORMATTER = DateTimeFormatter.ofPattern("dd.MM.yyyy HH:mm:ss", localeLoc);

    public static void main(String[] args) {
        // 格式化当前时间
        ZonedDateTime now = ZonedDateTime.now(GERMAN_ZONE);
        System.out.println("当前时间(java.time): " + now.format(OUTPUT_FORMATTER));

        // 解析日期并格式化
        String inputDate = "01.05.2018 00:00:00";
        LocalDateTime localDateTime = LocalDateTime.parse(inputDate, INPUT_FORMATTER);
        ZonedDateTime parsedZonedDate = localDateTime.atZone(GERMAN_ZONE);
        System.out.println("解析后格式化结果(java.time): " + parsedZonedDate.format(OUTPUT_FORMATTER));
    }
}

这个代码的输出会直接显示MESZ,而且线程安全,API设计也更清晰。

内容的提问来源于stack exchange,提问作者Fabian Hörstrup

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.29 06:57:48