I need to convert a standard long System.currentmillis to a temporal accessor and have no clue how to even begin.
Instant is a TemporalAccessor, so you can create an Instant from a number of milliseconds since the epoch:
TemporalAccessor ta = Instant.ofEpochMilli(System.currentTimeMillis());
Note that the docs for System.currentTimeMillis says that the granularity of the value depends on the OS, so it might not be the exact time in milliseconds.
Returns the current time in milliseconds. Note that while the unit of
time of the return value is a millisecond, the granularity of the
value depends on the underlying operating system and may be larger.
For example, many operating systems measure time in units of tens of
milliseconds.
Related
I was trying to save and restore timestamps in a database and stumbled upon this: Why does the second line not return 0?
Instant now = Instant.now();
System.out.println(now.compareTo(Instant.ofEpochMilli(now.toEpochMilli())));
I was expecting to get an instant that would represent the same moment in UTC, but when comparing the two instants as strings, it can be seen that some digits are cut off. What would be the proper way to store an instant in a database?
Example output from the above code:
897000
Output varies between runs but seems to be positive always, meaning that now is greater than Instant.ofEpochMilli(now.toEpochMilli()).
Instant may represent an instant in time with greater than millisecond precision.
The Instant.toEpochMilli() has this note:
If this instant has greater than millisecond precision, then the conversion will drop any excess precision information as though the amount in nanoseconds was subject to integer division by one million.
The result of Instant.ofEpochMilli(now.toEpochMilli()) however can never have greater than millisecond precision.
I already read an answer about if it's possible in Java 8 to get the current microseconds and the answer was no, but is it possible now in Java11?
The solution by using System.nanoTime() * 1000 is too inefficient.
Note: The Goal is NOT to get the exact current time in nanoseconds (for example 12:00 PM), obviously that's not working like this.
I would appreciate any help :)
As before, Instant.now() uses the most accurate time source available to the system. Depending on the system, there may not be anything finer-grained than System.currentTimeMillis.
As mentioned in the comments, System.nanoTime() / 1000 can be used for measuring the time between values, but doesn't give you anything like "the current time" -- you can't tell from it, for example, whether or not it's 3:00 PM.
If you need to measure or calculate e.g. the time between events in your program, there is nothing that will do better for you than System.nanoTime.
The Answer by Wasserman is correct. Here are more thoughts.
Not real-time
You commented:
When you try to do a very exact scheduler
Conventional implementations of Java, and conventional computer hardware, are not “very exact” along the scale of nanosecond and microsecond that you seemed to be targeting.
For “very exact” scheduling, you would have to use special hardware with special software. Look for the buzzword real-time, such as real-time Java.
System.nanoTime()
You said:
The solution by using System.nanoTime() * 1000 is too inefficient. Note: The Goal is NOT to get the exact time in nanoseconds
Be aware that System.nanoTime() does not tell you the current time.
System.nanoTime() tells you the approximate amount of nanoseconds that have elapsed since some arbitrarily chosen moment. In some implementations of Java, that moment may have been when the JVM was launched, or when the computer was booted, or something else. But you cannot count on that origin, nor should you care about the origin.
Represent elapsed time using Duration class.
To capture elapsed time in Java for micro-benchmarking:
long start = System.nanoTime() ;
…
Duration elapsed = Duration.between( start , System.nanoTime() ) ;
You can interrogate the Duration for its parts such as nanoseconds, whole seconds, minutes, and hours.
You said:
System.nanoTime() * 1000 is too inefficient
You must have meant:
( start - System.nanoTime() ) / 1_000
… to get a count of elapsed microseconds.
And, no, dividing or multiplying integers is not “inefficient“. If you care about optimizing for integer division operations, you should not be using conventional Java on conventional hardware, as discussed in section above.
Instant.now()
If you want to capture elapsed time as seen by human clocks:
Instant start = Instant.now() ; // May be precise to milliseconds, microseconds, or such depending on your implementation of Java and your host computer hardware clock.
…
Instant end = Instant.now() ;
To represent that elapsed time unattached to the timeline, use Duration.
Duration elapsed = Duration.between( start , end ) ;
To represent that elapsed time attached to the timeline, write a class storing a pair of Instant objects.
record SpanOfTime ( Instant start , Instant end ) {}
Or better yet, add the ThreeTen-Extra library to your project. This library brings classes that add functionality to the built-in java.time classes. One of these is Interval, with handy comparison methods such as abuts, contains, encloses, overlaps, etc.
I am using JDK8 on Windows and JDK8 on Linux
When I run System.nanoTime()/System.currentTimeMillis() on windows, the result is 49,
System.nanoTime(): 74786833960332
System.currentTimeMillis():1507786236263
When run it on Linux, the result is 26236
System.nanoTime(): 39560110918205325
System.currentTimeMillis():1507786262105
I am confused with the result, that the two values are different so much.
Also, I thought that nanoTime is 1,000,000 times milliseconds, so that the two values above both look wrong to me(that is, both of them should be approximately 1000000)
Apples and Oranges
System.nanotime has nothing to do with current date and time-of-day. Its purpose is for calculating elapsed time.
Your math and your comparison to System.currentTimeMillis() makes no sense at all. The two functions are incomparable.
Read the documentation before posting to Stack Overflow.
For date-time handling you should not be using the System class at all. Instead use the industry-leading java.time classes built into Java 8 and later.
If you want current moment in UTC, call Instant.now().
If you want current moment in a time zone, call ZonedDateTime.now.
In Java 9 and later, both classes use a new implementation of Clock to capture the current moment in a resolution up to nanoseconds. But keep in mind that mainstream computers lack a hardware clock with such fine sensitivity. Microseconds is likely the finest resolution you'll see in the real world as of 2017.
According to System.nanotime() docs it is not system time in nanoseconds and it is not related to System.currenTimeMillis. It is platform dependent (this is why the difference) nanoseconds generator and it is used for measuring time elapsed between two invocations.
From the Java System documentation:
[System.nanoTime] Returns the current value of the running Java Virtual Machine's high-resolution time source, in nanoseconds.
This means System.nanoTime() returns the elapsed running time of the JVM in nanos, whereas System.currentTimeMillis() returns the time in milliseconds since midnight, January 1, 1970 UTC.
This results in a non-consistent nanoTime over each run.
I'm using the epoch time format to save date. My problem is Java Long is enough to handle this or should I consider Java BigInteger to handle the epoch time?
Assuming you mean UNIX epoch, Java long is more then enough. UNIX epoch is number of seconds since January 1, 1970 and is stored (in UNIX) as a 32-bit int.
Yes, a long is sufficient. But in terms of the best way, consider using native types.
In Java <= 7, java.util.Date is designed for this purpose. It has millisecond precision.
In Java >= 8, java.time.Instant is designed for this purpose. It has nanosecond precision.
In Java you can get the milliseconds since the UNIX Epoch with System.currentTimeMillis() which returns a long, so there's no reason to consider something else.
If by epoch time, you mean seconds since 1970, long will of course do the job, as it can represent millis as well up until end of time ;-)
My point is that you can might integer instead. it will represent time in secs since 1970 up to year 2038.
If you don't need to represent time before now, consider using a special format like stated here. This will help you represent a wider future range.
Another option for representing time only after now, is starting the measure since 2021, by subtracting the seconds: nowSecs - 2021Secs.
I need help. I have been trying to figure out why java util date is 5 hours behind after converting from C# ticks.
in C#, the date is 6/8/2013 11:02:07 AM, I convert this date into ticks then pass it to java as long.
code snippet:
taken:
- long TICKS_AT_EPOCH = 621355968000000000L;
- long TICKS_PER_MILLISECOND = 10000;
java.util.Date date = new java.util.Date((ctime - TICKS_AT_EPOCH) / TICKS_PER_MILLISECOND);
Now java util date is Sat Jun 08 06:02:07 CDT 2013
Notice that the hour is 5 hours difference.
Any suggestions why?
You are constructing a java.util.Date based on milliseconds since 1/1/1970 UTC. You appear to be correcting from the fact that .net's System.DateTime.Ticks are based on 1/1/0001 and are 10,000 ticks to a millisecond. That is correct, but you have forgotten to adjust to UTC.
In .Net, the value coming from DateTime.Ticks is highly dependent on the DateTime.Kind property. There are three possible kinds of DateTime values.
DateTimeKind.Utc - This kind means that the value represents UTC time. It usually comes from a call to DateTime.UtcNow, but can also be constructed directly, and often is. For example, you might be retrieving UTC times from a database. You can feed the ticks from here directly into your conversion, and it will work.
DateTimeKind.Local - This usually comes from a call to DateTime.Now. The values are representative of the local time zone. You will need to convert to UTC before checking the ticks. You can do the following:
DateTime dt = DateTime.Now;
int utcTicks = dt.ToUniversalTime().Ticks;
Be aware that if the time happens during a daylight saving "fall-back" style transition, the result might be incorrect. The DateTime class has no idea about time zones. It just reflects the current local clock. If the value in dt is ambiguous, ToUniversalTime() will assume that the value is representative of standard time, even if you just retrieved it while in daylight time. This is just one of the many confusing and probablematic aspects of DateTime in .net.
DateTimeKind.Unspecified - This is the most common kind of DateTime you will encounter, and usually comes from DateTime.Parse() or a constructor like new DateTime(...). Unfortunately, there is nothing in here that will tell you about the time zone these dates are representative of. You can still try calling .ToUniversalTime(), but the framework will make the assumption that these times are representative of your local time zone, as if the kind was Local. That assumption could be completely wrong, depending on how you sourced the data. There really is no safe way to transform an Unspecified DateTime to a UTC value (ticks or otherwise).
There are some solutions, such as using DateTimeOffset instead of DateTime, or using the Noda Time library instead of the built-in types. You can read more about these problems here and here.
The time is not 5 hours behind, it's exactly the same time. The problem is with the way you print it.
You need to tell C# and Java to use the same time-zone when converting the date to string. One of them is using UTC and the other CDT.
java.util.date automatically corrects for your time zone. See this question: How to set time zone of a java.util.Date?
The ctime is UTC (Universal Coordinated Time), which is a time standard referenced to Greenwich. You're expressing your time in Central time. There's your difference.