【问题标题】:Formatting ISO 8601 in Java 7在 Java 7 中格式化 ISO 8601
【发布时间】:2017-09-19 12:29:42
【问题描述】:

我有这样的日期格式2016-11-25T09:29:10.588+01:00

我想将其转换为milliseconds,稍后在打印时我必须再次将毫秒转换为“yyyy-MM-dd HH:mm:ss.SSS”这种格式。

static FastDateFormat alarmDateFormat = FastDateFormat.getInstance("yyyy-MM-dd HH:mm:ss.SSS");
DateFormat df1 = new SimpleDateFormat("yyyy-MM-dd'T'hh:mm:ss.SSSXXX");
df1.setTimeZone(TimeZone.getTimeZone("UTC"));
String string1 = "2016-11-25T09:29:10.588+01:00";
Date result1 = df1.parse(string1);
long timeStamp = result1.getTime();
System.out.println("timeStamp : " +timeStamp);
String eventTime = alarmDateFormat.format(timeStamp);
System.out.println("AfterConverting : " + eventTime);

结果:

timeStamp : 1480062550588
AfterConverting : 2016-11-25 13:59:10.588

Date是正确的,但时间不同。我尝试将时区设置为“UTC”,但没有帮助。

请注意:在 Java 8 中,它可以与 Instant 等其他库以及我们在 Java 7 中想要的所有库一起正常工作。

【问题讨论】:

  • “我也尝试过设置时区“UTC”,但它没有帮助” - 它应该......如果你为FastDateFormat设置时区,那就是。请说明您是如何尝试设置时区的。
  • @HarshaG 始终使用新信息更新(您可以编辑)您的问题。
  • 那是在错误的格式化程序中设置时区...
  • “在 Java 8 中,它可以很好地与其他库(如 Instant)以及我们在 Java 7 中想要的所有库一起工作。”那么为什么不直接使用ThreeTen Backport?它在 Java 6 和 7 中提供现代 Java 日期和时间 API,包括 Instant 等。
  • 是的,您真的应该将 ThreeTen-Backport 添加到您的项目中。旧的遗留日期时间类是一团糟,令人困惑,设计糟糕。

标签: java datetime simpledateformat datetime-parsing


【解决方案1】:

你在df1中调用了setTimeZone,但是这个格式化程序只用于解析,对格式化没有任何作用。

要将日期格式化为特定时区,必须在其他格式化程序中设置(如果不设置,格式化程序使用 JVM 默认时区)。另外,你不需要依赖另一个类如FastDateFormat,你可以简单地使用另一个SimpleDateFormat

但要获得完全相同的日期/时间,您需要使用输入中使用的相同偏移量 (+01:00)。 Date 对象don't keep this information,因此您必须从输入中提取它。一种方法是使用substring:

SimpleDateFormat df1 = new SimpleDateFormat("yyyy-MM-dd'T'hh:mm:ss.SSSXXX");
String string1 = "2016-11-25T09:29:10.588+01:00";
Date result1 = df1.parse(string1);
long timeStamp = result1.getTime();
System.out.println("timeStamp : " + timeStamp);

// extract the +01:00 offset from the input
String offset = string1.substring(23);
SimpleDateFormat df2 = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS");
// set the offset in the formatter (so output is converted to it)
df2.setTimeZone(TimeZone.getTimeZone("GMT" + offset));
String eventTime = df2.format(timeStamp);
System.out.println("AfterConverting : " + eventTime);

输出将是:

时间戳:1480062550588
转换后:2016-11-25 09:29:10.588

如果你想继续使用FastDateFormat,也可以在里面设置时区:

FastDateFormat f = FastDateFormat.getInstance("yyyy-MM-dd HH:mm:ss.SSS", TimeZone.getTimeZone("GMT" + offset));
String eventTime = f.format(timeStamp);

Java 新的日期/时间 API

旧的类(DateCalendarSimpleDateFormat)有 lots of problemsdesign issues,它们正在被新的 API 取代。

对于 Java 7,您可以使用 ThreeTen Backport,这是 Java 8 新日期/时间类的一个很好的向后移植。对于Android,您还需要ThreeTenABP(更多关于如何使用它here)。

这样,您可以将输入解析为org.threeten.bp.OffsetDateTime,并使用org.threeten.bp.format.DateTimeFormatter 作为输出。在这种情况下,OffsetDateTime 保留了偏移信息,因此您无需在格式化程序中设置它:

OffsetDateTime odt = OffsetDateTime.parse(string1);
DateTimeFormatter fmt = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss.SSS");
System.out.println("timeStamp : " + odt.toInstant().toEpochMilli());
System.out.println("AfterConverting : " + odt.format(fmt));

输出是一样的:

时间戳:1480062550588
转换后:2016-11-25 09:29:10.588

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-02-01
    • 2019-04-08
    • 2016-03-06
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多