日期格式化程序产生不一致的结果

时间:2017-04-21 15:23:26

标签: java simpledateformat

我想显示格式化日期而不是时间戳。我的代码:

private static final String CRAWLER_DATE_FORMAT = "dd-MM-yyyy HH:mm:ss";
protected static final DateFormat DATE_FORMAT = new SimpleDateFormat(CRAWLER_DATE_FORMAT);

每3秒调用一次该日志行:

LOG.error("Timestamp: " + timestampString + " Formatted Date: " + DATE_FORMAT.format(Long.parseLong(timestampString));

我的日志:

Timestamp: 1491078405854 Formatted Date: 16-04-2017 21:25:20 <==
Timestamp: 1491078405854 Formatted Date: 01-04-2017 23:26:45
Timestamp: 1491078405854 Formatted Date: 01-04-2017 23:26:45
Timestamp: 1491078405854 Formatted Date: 01-04-2017 23:26:45
Timestamp: 1491078405854 Formatted Date: 01-04-2017 23:26:45
Timestamp: 1491078405854 Formatted Date: 16-04-2017 21:25:20 <==
Timestamp: 1491078405854 Formatted Date: 01-04-2017 23:26:45

为什么我会得到不同的结果?

1 个答案:

答案 0 :(得分:2)

TL;博士

Instant.ofEpochMilli( yourLongNumber );
       .toString()

详细

旧的日期时间类在其众多缺陷中缺乏线程安全性。

使用取代麻烦遗留类的java.time类。 java.time类使用不可变对象并且是线程安全的。

Instant instant = Instant.ofEpochMilli( yourLongNumber );
String output = instant.toString();
  

2017-01-23T12:34:56.789Z

如果您不喜欢T,请拨打String::replace或使用DateTimeFormatter。这两个都在Stack Overflow上的许多其他问题和答案中显示。

要获得格式灵活性,请将基本Instant转换为OffsetDateTime对象。

DateTimeFormatter f = DateTimeFormatter.ofPattern( "dd-MM-uuuu HH:mm:ss" , Locale.US );
String output = instant.atOffset( ZoneOffset.UTC ).format( f );

我建议尽可能坚持使用java.time类中默认使用的标准ISO 8601格式。标准格式非常适合日志记录,这似乎是您的问题的领域。

您所需的格式是不明智的,因为它没有偏移或区域的指示。这种缺乏可能导致人们对偏移/区域做出错误的假设并误解他们正在阅读的内容。所以我强烈建议总是包括偏移/区域信息。我还建议您使用UTC进行所有日志记录。程序员和管理员都应该学会将UTC视为唯一的真实时间。