Reputation: 17
While logging some messages to console with time stamps for debugging, I noticed that the time stamps were not being update when printed. The messages of the exact time even when they are several seconds apart at random intervals.How do you get the current exact time?
Code used (from 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);
}
}
Upvotes: 0
Views: 1281
Reputation: 338805
The accepted Answer by NikhilChilwant is correct. The Date instance was being held rather than re-generated. But the Question and that Answer are both using outdated classes.
The old troublesome java.util.Date/.Calendar classes have been supplanted by the java.time framework in Java 8 and later. Defined by JSR 310, inspired by Joda-Time.
ZonedDateTime zdt = ZonedDateTime.now();
That line above implicitly assigns the JVM’s current default time zone. I strongly recommend always specifying your desired/expected time zone explicitly.
ZoneId zoneId = ZoneId.of( "Europe/Paris" );
ZonedDateTime zdt = ZonedDateTime.now( zoneId );
You can easily get a textual representation of the date-time value.
String output = zdt.toString();
2016-01-29T10:15:30+01:00[Europe/Paris]
By default that toString
method generates a String using a sensible format defined by the ISO 8601 standard. Actually, that format extends the ISO 8601 standard by appending the name of the time zone in brackets.
You can create Strings in other formats by using the java.time.format package.
The general best practice for business logic, data storage/exchange, serialization, and logging is to use UTC instead of any particular time zone.
Instant
For UTC-only purposes, call upon the simple Instant
class which represents a moment on the timeline in UTC. As it always uses UTC you need not pass a time zone, unlike the ZonedDateTime
you saw above.
Instant instant = Instant.now();
String output = instant.toString().
The toString
method on Instant
also uses ISO 8601. Its fraction-of-second uses zero, three, six, or nine digits as needed to represent the fraction to millisecond, microsecond, or nanosecond. Currently in Java 8 Update 72, the clock implementation used by .now
will only generate values up to milliseconds.
2016-12-03T10:15:30Z
The java.time framework uses immutable objects. Instead of altering the values of a java.time object’s members, we create a new instance based mostly on the old object’s values excepting our particular desired alternate value.
A java.time object such as Instant
or ZonedDateTime
does not ever change its member values. The object will not automatically update to the current moment. Each time you want to capture the current moment, call that now
method to instantiate a new fresh object.
While it is fine to roll-your-own logging when first starting out, I suggest you eventually learn to use the SLF4J logging façade framework. As a façade, you can sprinkle SLF4J calls all over your code base. But at runtime those calls fall through to an actual logging implementation. If starting out fresh, use LogBack. LogBack is made by the same folks as SLF4J and gets called directly without need for going through an adapter.
If a project is already using one of the older Java logging frameworks, an adapter can translate the SLF4J calls. That is the whole point to SLF4J: avoid getting locked into any one implementation.
Upvotes: 2
Reputation: 649
Try this :
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);
}
}
Why this works?
With your code, time
gets updated only when new instance of Debug
is created. Instead , you want it to get updated whenever log()
is called. So, update it there.
Upvotes: 3