繁体   English   中英

带有TimeZone的SimpleDateFormat

[英]SimpleDateFormat with TimeZone

我正在尝试从java.util.Date格式化日期。 我需要这种格式:

2016-06-10T13:38:13.687+02:00

如何从标准日期格式正确转换它

May 04 09:51:52 CDT 2009

SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss z", Locale.getDefault());
sdf.format(new Date());

遗憾的是,此代码返回的值不是+02:00

根据标准Java文档: https//docs.oracle.com/javase/7/docs/api/java/text/SimpleDateFormat.html

获取日期和时间格式

2001-07-04T12:08:56.235-07:00


你需要使用下面的String模式:

“YYYY-MM-dd'T'HH:MM:ss.SSSXXX”

因此,使用以下代码,您可以得到您想要的:

SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSSXXX", Locale.getDefault());
    simpleDateFormat .format(new Date());

只需将你的z转换为upperCase即可

    SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss Z", Locale.getDefault());
    sdf.format(new Date());

结果:2016-06-10T13:53:22 +0200

您最后添加(ZZZZZ)以获得如下格式

SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss ZZZZZ", Locale.getDefault());

以格式添加SSSZ

"yyyy-MM-dd'T'HH:mm:ss z" => "yyyy-MM-dd'T'HH:mm:ss.SSSZ"

只需改变这一行

旧: SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss z", Locale.getDefault()); sdf.format(new Date()); SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss z", Locale.getDefault()); sdf.format(new Date());

新增功能: SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSSZ", Locale.getDefault());

是时候有人提供现代答案了。

    OffsetDateTime now = OffsetDateTime.now(ZoneId.of("Africa/Cairo"));
    String formatted = now.toString();
    System.out.println(formatted);

这只是印刷

2018-02-28T16:42:59.628526 + 02:00

编辑:我在秒上要求3位小数,而不是6.要对格式进行更多控制,请使用显式格式化程序:

    DateTimeFormatter formatterWithThreeDecimals
            = DateTimeFormatter.ofPattern("uuuu-MM-dd'T'HH:mm:ss.SSSXXXXX");
    String formatted = now.format(formatterWithThreeDecimals);
    System.out.println(formatted);

打印(在我编辑时):

2018-04-30T15:47:41.749 + 02:00

如果不是非洲/开罗,请替换您想要的时区。 为JVM的时区设置指定ZoneId.systemDefault() 可以通过程序的另一部分或在同一JVM中运行的其他程序随时更改该设置。

使用java.time,现代Java日期和时间API,如果你只想要一个符合ISO 8601的utput并且不关心多少小数(或者如果它们是0则打印秒数),我们不需要一个明确的格式化器。 您想要的字符串是ISO 8601格式,这是现代类的toString方法生成的标准格式。 根据您的需要,可能会接受toString的结果。

你使用的类, DateSimpleDateFormat ,已经过时了,后者尤其出了名的麻烦。 我建议你避免它们,而是使用现代API。 与它合作真是太好了。

如果您从遗留API获得了一个java.util.Date ,您现在不想更改它,请将其转换为现代Instant并从那里进行进一步的转换。 在Java 8及更高版本中,这种情况如下:

    ZonedDateTime dateTime = oldfashionedDateFromLegacyApi.toInstant()
            .atZone(ZoneId.of("Africa/Cairo"));
    String formatted = dateTime.format(DateTimeFormatter.ISO_OFFSET_DATE_TIME);

如果您使用的是ThreeTen Backport和/或ThreeTenABP,则转换的方式会略有不同,如下所示:

    ZonedDateTime dateTime = DateTimeUtils.toInstant(oldfashionedDateFromLegacyApi)
            .atZone(ZoneId.of("Africa/Cairo"));

同样,如果您想要对输出格式进行严密控制,请不要使用DateTimeFormatter.ISO_OFFSET_DATE_TIME因为它将输出1到9位小数的任何内容,如果它们为0,也可以省略秒。而是使用上面的formatterWithThreeDecimals

问题:我可以在Android上使用java.time吗?

是的, java.time在Android上运行良好。 它至少需要Java 6

  • 在Java 8及更高版本和更新的Android设备上,现代API内置。
  • 在Java 6和7中获取ThreeTen Backport,新类的后端端口(适用于JSR 310的ThreeTen;请参见底部的链接)。
  • 在(较旧的)Android上使用Android版的ThreeTen Backport。 它被称为ThreeTenABP。 并确保从子包中导入org.threeten.bp的日期和时间类。

链接

你犯了一个简单的错误,你需要使用大写z 你需要的是:

SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss z Z", Locale.getDefault());

除了你的小写z 小写的z为您提供了时区,但是大写字母为您提供了基于RFC 822的时区。

编辑

如果您不想要通常的时区,只需要+2:00而不需要PST,您只需要一个大写Z:

   SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss Z", Locale.getDefault());

从(非常简单的可理解) 文档

z/zz/zzz:PST zzzz:Pacific Standard Time
Z/ZZ/ZZZ:-0800 ZZZZ:GMT-08:00 ZZZZZ:-08:00

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM