在将某些消息记录到控制台并使用时间戳进行调试时,我注意到打印时没有更新时间戳。准确时间的消息,即使它们以随机间隔相隔几秒钟。你如何得到当前的确切时间?
使用的代码(来自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);
}
}
答案 0 :(得分:3)
试试这个:
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()
时更新它。所以,在那里更新。
答案 1 :(得分:2)
accepted Answer by NikhilChilwant是正确的。 Date实例被保留而不是重新生成。但问题和答案都使用过时的类。
旧的麻烦的java.util.Date/.Calendar类已被Java 8及更高版本中的java.time框架取代。由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标准定义的合理格式生成String。实际上,该格式通过在括号中附加时区名称来扩展ISO 8601标准。
您可以使用java.time.format包创建其他格式的字符串。
业务逻辑,数据存储/交换,序列化和日志记录的一般最佳做法是使用UTC而不是particular time zone。
Instant
仅限UTC,请调用简单的Instant
类,该类代表UTC时间轴上的时刻。由于它始终使用UTC,因此您不需要传递时区,这与您在上面看到的ZonedDateTime
不同。
Instant instant = Instant.now();
String output = instant.toString().
toString
上的Instant
方法也使用ISO 8601.它的小数部分根据需要使用零,三,六或九位数来表示毫秒,微秒或纳秒的分数。目前在Java 8 Update 72中,.now
使用的时钟实现仅生成高达毫秒的值。
2016-12-03T10:15:30Z
java.time框架使用immutable objects。我们不是改变java.time对象成员的值,而是主要基于旧对象的值创建一个新实例,除了我们特定的期望替代值。
诸如Instant
或ZonedDateTime
之类的java.time对象永远不会更改其成员值。该对象不会自动更新到当前时刻。每次要捕获当前时刻时,请调用now
方法来实例化新的新对象。
虽然在首次启动时滚动自己的日志记录是可以的,但我建议您最终学会使用SLF4J日志记录框架。作为外观,您可以在代码库中遍布SLF4J调用。但是在运行时,这些调用将进入实际的日志记录实现。如果刚开始,请使用LogBack。 LogBack由与SLF4J相同的人员制作,并且无需通过适配器即可直接调用。
如果项目已经使用了一个较旧的Java日志记录框架,则适配器可以转换SLF4J调用。这就是SLF4J的重点:避免被锁定到任何一个实现中。