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

Date formatter produces inconsistent results

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

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

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

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 格式。标准格式非常适合日志记录,这似乎是您问题的领域。

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