【问题标题】:Calling instance of date() does not update time调用 date() 实例不会更新时间
【发布时间】:2016-05-03 20:52:33
【问题描述】:

在将一些带有时间戳的消息记录到控制台以进行调试时,我注意到时间戳在打印时并未更新。准确时间的消息,即使它们以随机间隔相隔几秒。如何获得当前准确时间?

使用的代码(来自https://stackoverflow.com/a/23068721/5562296):



    package creatorsuperman.PrgLog;  
public class Debug {
    public String time = new SimpleDateFormat("yyyy.MM.dd.HH.mm.ss").format(new Date());
    public void log(String msg) {
        System.out.println(time + " : " + msg);
    }
}

【问题讨论】:

  • 当您创建Debug 的实例时,您会创建一个当前日期/时间的格式化String 并继续打印...您永远不会再真正更新String

标签: java date datetime


【解决方案1】:

试试这个:

public class Debug {

    public void log(String msg) {
        String time = new SimpleDateFormat("yyyy.MM.dd.HH.mm.ss").format(new Date());
        System.out.println(time + " : " + msg);
    }
}

为什么会这样? 使用您的代码,time 仅在创建 Debug 的新实例时才会更新。相反,您希望在调用 log() 时更新它。所以,在那里更新它。

【讨论】:

  • 正确答案。尝试添加一些讨论以进行教育。就像上面看到的 MadProgrammer 的评论一样。 Stack Overflow 不仅仅是一个代码 sn-p 库。
【解决方案2】:

java.time

accepted Answer by NikhilChilwant 是正确的。 Date 实例被保留而不是重新生成。但是问题和答案都使用过时的类。

Java 8 及更高版本中的 java.time 框架已取代了旧的麻烦 java.util.Date/.Calendar 类。由 JSR 310 定义,受 Joda-Time 启发。

ZonedDateTime zdt = ZonedDateTime.now();

上面那一行隐式分配了 JVM 当前的默认时区。我强烈建议始终明确指定所需/预期的时区。

ZoneId zoneId = ZoneId.of( "Europe/Paris" );
ZonedDateTime zdt = ZonedDateTime.now( zoneId );

字符串

您可以轻松获得日期时间值的文本表示。

String output = zdt.toString();

2016-01-29T10:15:30+01:00[欧洲/巴黎]

默认情况下,toString 方法使用ISO 8601 标准定义的合理格式生成字符串。实际上,该格式通过在括号中附加时区名称来扩展 ISO 8601 标准。

您可以使用 java.time.format 包创建其他格式的字符串。

UTC

业务逻辑、数据存储/交换、序列化和日志记录的一般最佳实践是使用UTC 而不是任何particular time zone

Instant

仅出于 UTC 目的,调用简单的 Instant 类,它代表 UTC 时间轴上的时刻。由于它始终使用 UTC,因此您无需传递时区,这与您在上面看到的 ZonedDateTime 不同。

Instant instant = Instant.now();
String output = instant.toString().

Instant 上的 toString 方法也使用 ISO 8601。它的秒分数根据需要使用零、三、六或九位数字来表示毫秒、微秒或纳秒的分数。目前在 Java 8 Update 72 中,.now 使用的时钟实现只能生成毫秒级的值。

2016-12-03T10:15:30Z

不可变对象

java.time 框架使用immutable objects。我们不是更改 java.time 对象成员的值,而是主要基于旧对象的值创建一个新实例,除了我们特别需要的替代值。

InstantZonedDateTime 等 java.time 对象永远不会更改其成员值。对象不会自动更新到当前时刻。每次你想捕捉当前时刻,调用 now 方法来实例化一个新的对象。

日志框架

虽然在刚开始时滚动自己的日志记录很好,但我建议您最终学会使用SLF4J 日志记录外观框架。作为外观,您可以将 SLF4J 调用散布在您的代码库中。但是在运行时,这些调用会落入实际的日志记录实现中。如果刚开始,请使用LogBack。 LogBack 由与 SLF4J 相同的人制作,无需通过适配器即可直接调用。

如果项目已经在使用旧的 Java 日志框架之一,适配器可以转换 SLF4J 调用。这就是 SLF4J 的重点:避免陷入任何一种实现。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-02-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-04-24
    • 2021-06-09
    相关资源
    最近更新 更多