奇怪的Java时区日期转换问题

发布于 2024-11-29 10:07:32 字数 1130 浏览 0 评论 0原文

我想将 ms-since-1970-timestamp 转换为带有时区的日期(德国)。

这里有两个有效的代码变体 - 至少,我记得使用过它并且它有效:

import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.GregorianCalendar;
import java.util.Locale;
import java.util.TimeZone;

public class TestDate {

    public static void main(String[] args) {
        Calendar cal = GregorianCalendar.getInstance(TimeZone.getTimeZone("Germany"), Locale.GERMANY);

        Date d = new Date();
        cal.setTime(d);

        System.out.println(String.format("%02d.%02d.%04d %02d:%02d:%02d", 
                cal.get(Calendar.DAY_OF_MONTH), cal.get(Calendar.MONTH)+1, cal.get(Calendar.YEAR),
                cal.get(Calendar.HOUR_OF_DAY),  cal.get(Calendar.MINUTE),  cal.get(Calendar.SECOND)));

        SimpleDateFormat df = new SimpleDateFormat( "dd.MM.yyyy HH:mm:ss.S" );
        df.setTimeZone(TimeZone.getTimeZone("Germany"));
        System.out.println(df.format(d));
    }

}

这真的很奇怪,因为我找不到 2 小时时差的原因。

它应该是:16:05:20 代码在两种变体中都会打印:14:05:20

有人可以帮助我并告诉我这里出了什么问题吗?

I want to convert ms-since-1970-timestamp to a date with timezone (Germany).

Here are two variants of code which worked - at least, I remember using it and it worked:

import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.GregorianCalendar;
import java.util.Locale;
import java.util.TimeZone;

public class TestDate {

    public static void main(String[] args) {
        Calendar cal = GregorianCalendar.getInstance(TimeZone.getTimeZone("Germany"), Locale.GERMANY);

        Date d = new Date();
        cal.setTime(d);

        System.out.println(String.format("%02d.%02d.%04d %02d:%02d:%02d", 
                cal.get(Calendar.DAY_OF_MONTH), cal.get(Calendar.MONTH)+1, cal.get(Calendar.YEAR),
                cal.get(Calendar.HOUR_OF_DAY),  cal.get(Calendar.MINUTE),  cal.get(Calendar.SECOND)));

        SimpleDateFormat df = new SimpleDateFormat( "dd.MM.yyyy HH:mm:ss.S" );
        df.setTimeZone(TimeZone.getTimeZone("Germany"));
        System.out.println(df.format(d));
    }

}

It's really strange, because I couldn't find the reason for a time-difference of 2hours.

It should be: 16:05:20
The code prints: 14:05:20 in both variants.

Could someone please help me and tell me what went wrong here?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

思念绕指尖 2024-12-06 10:07:32

这就是问题所在:

TimeZone.getTimeZone("Germany")

没有这样的时区 ID,因此 Java 以其无限的智慧决定只返回 UTC,而不告诉您有什么问题。试试这个:

TimeZone.getTimeZone("Europe/Berlin")

维基百科有一个 IANA 时区 ID 列表,但它有点超出了日期(撰写本文时); IANA 数据 是最新的,但不太容易浏览...

This is the problem:

TimeZone.getTimeZone("Germany")

There's no such time zone ID, so Java in its infinite wisdom decides to just return you UTC without telling you that anything's wrong. Try this instead:

TimeZone.getTimeZone("Europe/Berlin")

Wikipedia has a list of IANA time zone IDs, but it's somewhat out of date (at the time of writing); the IANA data is the most up-to-date, but it's not as easily browsable...

寄居者 2024-12-06 10:07:32

我相信问题出在您运行的平台上的默认时区。

java.util.Date() 确实有一个时区。它维护“继承的”时区信息,这些信息似乎是从系统的默认区域设置获取的。

这段代码。

TimeZone tz = TimeZone.getTimeZone("GMT-03:00");
Calendar cal = Calendar.getInstance(tz);
cal.set(1953, 2, 22, 4, 20, 13);
Date dateTime = cal.getTime();
System.out.println(dateTime.toString());

在我的系统上产生这个,它使用 PST 语言环境:Sat Mar 21 23:20:13 PST 1953。

我不相信有办法使用 java.util.Date 对象或使用它的 DateFormat 对象,以准确处理来自“外国”时区的时间信息。

I believe the problem is the default timezone on the platform you're running on.

java.util.Date() does have a time zone. It maintains "inherited" time zone information, which, it appears, is acquired from the system's default locale.

this code.

TimeZone tz = TimeZone.getTimeZone("GMT-03:00");
Calendar cal = Calendar.getInstance(tz);
cal.set(1953, 2, 22, 4, 20, 13);
Date dateTime = cal.getTime();
System.out.println(dateTime.toString());

yields this on my system, which is uses the PST locale: Sat Mar 21 23:20:13 PST 1953.

I don't believe that there is a way to use the java.util.Date object, or the DateFormat objects which use it, to accurately handle time information from a "foreign" time zone.

圈圈圆圆圈圈 2024-12-06 10:07:32

Jon Skeet 的回答是正确的,您使用了不正确的时区名称。

java.time

这是使用现代 的解决方案java.time 类取代了旧的遗留日期时间类,这些类已被证明是非常麻烦和令人困惑的。

Instant instant = Instant.ofEpochMilli( milliseconds_since_1970 );  // Or Instant.now() for current moment.
ZoneId z = ZoneId.of( "Europe/Berlin" ); 
ZonedDateTime zdt = instant.atZone( z );

生成本地化字符串来表示该日期时间值。

Locale l = Locale.GERMANY; // Or Locale.CANADA_FRENCH, etc.
DateTimeFormatter f = DateTimeFormatter.ofLocalizedDateTime( FormatStyle.SHORT ).withLocale( l );
String output = zdt.format( f );

表格Java 中的日期时间类型(现代和传统)

The Answer by Jon Skeet is correct, you used an incorrect time zone name.

java.time

Here is a solution using the modern java.time classes that supplant the old legacy date-time classes that have proven to be so troublesome and confusing.

Instant instant = Instant.ofEpochMilli( milliseconds_since_1970 );  // Or Instant.now() for current moment.
ZoneId z = ZoneId.of( "Europe/Berlin" ); 
ZonedDateTime zdt = instant.atZone( z );

Generate a localized string to represent that date-time value.

Locale l = Locale.GERMANY; // Or Locale.CANADA_FRENCH, etc.
DateTimeFormatter f = DateTimeFormatter.ofLocalizedDateTime( FormatStyle.SHORT ).withLocale( l );
String output = zdt.format( f );

Table of date-time types in Java, both modern and legacy

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文