【问题标题】:SimpleDateFormat produces different timezone outputs in Android vs JDKSimpleDateFormat 在 Android 和 JDK 中产生不同的时区输出
【发布时间】:2023-03-04 03:43:01
【问题描述】:

这里有很多关于 SimpleDateFormat 的问题,但我似乎在这个问题上找不到任何东西。我遇到了在 Android 和 JDK 上运行的完全相同的代码输出不同的问题。我在 Eclipse 中运行并使用模拟器来测试 Android。 JDK 版本 1.7 和 Android 4.4。

关于如何以 JDK 样式格式制作 Android 输出日期的任何想法?

TimeZone GMT_ZONE = TimeZone.getTimeZone("GMT");
String RFC1123_PATTERN = "EEE, dd MMM yyyy HH:mm:ss z";

final DateFormat rfc1123Format = new SimpleDateFormat(RFC1123_PATTERN, LOCALE_US);
rfc1123Format.setTimeZone(GMT_ZONE);
String dateString = rfc1123Format.format(new Date()); 

JDK 1.7 dateString 值:2013 年 12 月 20 日星期五 00:46:21 GMT

Android 4.4 dateString 值:2013 年 12 月 20 日星期五 00:46:21 GMT+00:00

【问题讨论】:

  • Android 是一个有一些不同的重新实现,也许尝试不同的模式? stackoverflow.com/questions/10584647/…
  • 很遗憾您正在使用模拟器。天哪,它很慢。您必须依赖 Android 使用的内容或从模式中删除“z”
  • 是的,我确实意识到 Android 和 JDK 是不同的(因此为什么我必须做这么多工作才能让它们玩得更好)。但是,我确实需要 JDK 样式的模式,因为我正在使用另一个需要该格式的服务。知道什么模式会在 Android 上产生 Fri, 20 Dec 2013 00:46:21 GMT 格式输出吗?

标签: java android date simpledateformat


【解决方案1】:

Android != Java

Android 库是对 Java 库的模仿,但并非完全复制。因此the lawsuit between Oracle and Google。所以你可能会看到行为的变化。

乔达时间

如果您想要在使用日期时间时获得一致且卓越的体验,请使用第三方开源 Joda-Time 库。 Joda-Time 旨在取代臭名昭著的 java.util.Date/Calendar 类。

JSR 310

另一个选项可能是与 Java 8 捆绑在一起的 JSR 310: Date and Time APIjava.time.* 类的 Java 7 反向移植。

RFC 1123 格式

关于您作为评论添加的后续问题:

知道什么模式会在 Android 上产生 Fri, 20 Dec 2013 00:46:21 GMT 格式的输出吗?

令人惊讶的是,Joda-Time 2.3 似乎缺少用于旧 RFC 1123 格式的内置格式化程序。但是下面的自制格式似乎可以完成这项工作,前提是您记得将 DateTime 转换为 UTC,如下所示。

// © 2013 Basil Bourque. This source code may be used freely forever by anyone taking full responsibility for doing so.
// import org.joda.time.*;
// import org.joda.time.format.*;

DateTime nowInParis = new DateTime( DateTimeZone.forID( "Europe/Paris" ) );

DateTimeFormatter formatter = DateTimeFormat.forPattern("E, d MMM yyyy HH:mm:ss 'GMT'").withLocale( Locale.US );
String nowInParisAsStringGMT = formatter.print( nowInParis.toDateTime( DateTimeZone.UTC ) );

转储到控制台...

System.out.println( "nowInParisAsStringGMT: " + nowInParisAsStringGMT );
System.out.println( "nowInParis: " + nowInParis );

运行时……

nowInParisAsStringGMT: Fri, 20 Dec 2013 05:03:58 GMT
nowInParis: 2013-12-20T05:03:58.175+01:00

【讨论】:

  • 谢谢!我确实意识到它们是不同的,但是考虑到两者都有“z”应该产生 GMT(而不是 GMT+)样式输出的示例,我想知道这是一个已知的错误还是我误解了文档。也许我需要一些额外的设置?
  • 我不知道您的设置问题的答案。但我知道,如果您继续使用 java.util.Date/Calendar 类或它们在 Android 中的模仿,那么这只是等待您的众多头痛中的第一个。没有理由不使用 Joda-Time(或 JSR 310 的反向移植),但有一个原因:有些人报告在 Andoid 中首次调用 Joda-Time 时速度变慢(仅限 Android,在真正的 Java 平台上完全没有问题)。我不知道减速问题的细节。但请注意,您要调查该问题,我强烈建议您切换到 Joda-Time 或 JSR 310,并且永远不要回头。
  • 我不确定我是否能够使用 JodaTime,但如何使用它的详细描述(以及 Android 警告)很有帮助。我暂时将您标记为答案,除非其他人可以回答更复杂的格式后续问题。
【解决方案2】:

对于那些不想使用 Joda-Time 的人来说,这是 Basil 答案的略微修改版本:

private String toRfc1123(Date date) {
    SimpleDateFormat formatter = new SimpleDateFormat("EEE, dd MMM yyyy HH:mm:ss 'GMT'", Locale.US);
    formatter.setTimeZone(TimeZone.getTimeZone("GMT"));
    return formatter.format(date);
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-09-30
    • 2021-11-24
    • 2012-12-14
    • 2013-10-02
    • 1970-01-01
    • 2014-05-06
    相关资源
    最近更新 更多