Accuracy of unix utc epoch time in seconds in java - java

I have seen people using System.currentTimeInMillis and converting it into seconds to store unix utc epoch time. But in Java 8 we can also use Instant.ofEpochSeconds. Which one is more accurate? Is it better to use Instant.ofEpochMillis and convert it into seconds for better accuracy ?

Well, Instant.ofEpochSecond(long) takes an argument and is used to represent an Instant. I think you meant Instant.now() which says (in part)
This will query the system UTC clock to obtain the current instant.
And, system UTC clock says (in part)
This may use System.currentTimeMillis(), or a higher resolution clock if one is available.
So the answer is, it depends. But calling System.currentTimeMillis() which (per the Javadoc) returns
the difference, measured in milliseconds, between the current time and midnight, January 1, 1970 UTC.
Note that unix epoch is in seconds.

Related

java.time: the simplest way to get a difference in hours between two LocalTime objects

I want to get a difference in hours between a current time in a specific timezone and UTC time. I tried this:
LocalTime time = LocalTime.now();
System.out.println(time); //21:05:42:764
LocalTime utcTime = LocalTime.now(ZoneId.of("UTC"));
System.out.println(utcTime); //18:05:42:769
System.out.println(Duration.between(utcTime, time).getSeconds()/3600); //2
System.out.println(Duration.between(time, utcTime).getSeconds()/3600); //-3
Why is the difference between the last two results and are there better ways to do it? I need to get the number 3.
Why is the difference between the last two results
The reason that you're getting different results for the two computed durations is a combination of the fact that there is some tiny amount of time elapsed between the two recordings and the fact that the duration start time is included in the range but the duration end time is not.
Consider these times instead: 6:00:00:001 vs 8:00:00:000. Here it is very obvious that we're only exactly one millisecond off of two hours, but when we think about seconds we're either going to get 7199 or -7200. When we then do integer math (i.e. divide by 3600), we're going to get 1 or -2.
If it weren't for the one extra millisecond on the first timestamp, the absolute value of the two would be identical.
Duration is the wrong class. There is zero duration between "now" in one time zone and "now" in another. For a fun but memorable way to think about this, see here.
You appear to be seeking to know the current offset from UTC for a given time zone. You can use the ZonedDateTime class for that:
ZonedDateTime zdt = ZonedDateTime.now(ZoneId.of("Asia/Kolkata"));
ZoneOffset offset = zdt.getOffset();
int offsetMinutes = offset.getTotalSeconds() / 60;
double offsetHours = ((double) offsetMinutes) / 60;
System.out.println(offsetHours); // 5.5
You could also just use ZonedDateTime.now() on the first line, if you want to use the computer's current time zone.
With regard to LocalTime - that is just the time portion (hours, minutes, seconds, and smaller). Since there is no date associated, you can't necessarily determine which time zone offset it belongs to. There is more than one date that "today" going on at any given moment. Time zone offsets range from UTC-12 to UTC+14, so there are indeed values where the same time of day is happening on two different dates somewhere on the planet.
As an example, 08:00:00 in Hawaii (Pacific/Honolulu) on 2019-01-01 is also 08:00:00 in Kiribati (Pacific/Kiritimati), but on 2019-01-02 - the following date! (Reference here.) Thus, if you had a LocalTime object with 08:00:00 and it was 08:00:00 in one of those two zones, you'd not be able to tell which one it was, or what the corresponding UTC offset should be.
Also, keep in mind that time zone offsets are not limited to whole hours. There are present-day time zones with half-hour and 45-minute offset. Historically, there have been others.
Lastly, keep in mind that an offset is not necessarily enough to identify a time zone. Many time zones share offsets at some points in time, but differ in others. See "Time Zone != Offset" in the timezone tag wiki.
Oh, and about your results getting 2 in one direction and -3 in the other - this is a rounding error due to your integer division. If you print out the seconds value, you'll notice they are one second apart (10799, vs -10800). Dig closer and you'll find that "now" included fractional seconds that were truncated with the getSeconds call. (You called .now() twice, so they were at slightly different times.)

Name of a standard for time representation in milliseconds

I'm looking for the name of the standard for time, represented in milliseconds since midnight January 1, 1970 UTC. We can get one calling System.currentTimeMillis() in Java. For example when we are talking about the same time, represented in seconds - we use term Unix time. It would be great if you provide a link to standard in the answer.
In the GNU Linux documentation it is called:
seconds since the epoch
Extrapolating you could call it milliseconds since the epoch.

System.currentTimeMillis measuring time

When I use System.currentTimeMillis() to measure the time, is it safe?
E.g. When a time-shift happens (summer->winter time) will this produce an error?
No, System.currentTimeMillis() returns the number of elapsed milliseconds since the Unix epoch (midnight at the start of January 1st 1970, UTC). This does not depend on your local time zone at all.
In other words, if you call it once per second, it will always increase by about 1000 (the "about" is only due to clock accuracy and the impossibility of the calls being exactly 1 second apart). It doesn't matter if your local time zone changes its offset from UTC, or if you even change your whole time zone - that will be irrelevant.
In theory, leap seconds make all of this trickier - but in practice most applications can get away with notionally sticking their fingers in their ears and saying "I'm not at home to Mr Leap Second."
System.currentTimeMillis() will return the milliseconds since epoch (1/1/1970 00:00:00). How those are interpreted is a completely different story (and summer/winter time as well as timezone belong to the interpretation part). So yes, it would be save.

generate exact clock time in seconds and express time zone offset as well

I am generating Continuity Of Care document that requires effective time. The document states:
CONF-9: ClinicalDocument / effectiveTime SHALL be expressed with precision to include seconds.
CONF-10: ClinicalDocument / effectiveTime SHALL include an explicit time zone offset.
Well, I can get current time in seconds:
long timeMillis = System.currentTimeMillis();
long timeSeconds = TimeUnit.MILLISECONDS.toSeconds(timeMillis);
But I have no idea what the second part says about having time zone. A example of correct effective time would be 20000407130000+0500. It is from one of the sample.
System.currentTimeMillis() is UTC by definition.
From the javadoc
the difference, measured in milliseconds, between the current time and midnight, January 1, 1970 UTC.
Just hard code UTC as the time zone for your timestamps.

Printing milliseconds of Java epoch returns 18000000?

In Joda, if I print
DateTime(GregorianChronology.getInstance())
.withYear(1970)
.withMonthOfYear(1)
.withDayOfMonth(1)
.withHourOfDay(0)
.withMinuteOfHour(0)
.withSecondOfMinute(0)
.withMillisOfSecond(0).getMillis();
I see 18000000 (this also happens to be 1/4th of MILLIS_PER_DAY, FWIW).
What I don't understand is that if the milliseconds represents the offset from the epoch which is defined as Jan-1970-01-01, then shouldn't the milliseconds be 0?
The epoch is Jan-1970-01-01 GMT. The instance you have, obviously has a different DateTimeZone. In fact it lookds like you're at GMT+5. (18000000 millis = 5 hours)
I believe the issue is related to the way Java dates include the time zone as part of there calculations.
For me, this means I'm +10 hours ahead of the epoc.
Try creating a Date/Time value that is set to 0 GMT.
The "epoch" is a specific and universal instant, a point in the universe time (like, say the moment in which the Apollo XI landed on the moon). This reference point can be represented differently in different countries (and a martian could also represent it with his own calendar). For example, for the people in England (GMT), that's the moment in which the hands of their clocks marked "00:00:00" and their (Gregorian) calendars marked "1/1/1970"; but that's just an example.
The line
DateTime(GregorianChronology.getInstance()).withYear(1970).withMonthOfYear(1)
.withDayOfMonth(1).withHourOfDay(0).withMinuteOfHour(0)
.withSecondOfMinute(0).withMillisOfSecond(0)
gives you the instant in which the clocks and the calendars in your country marked "00:00:00 1970-01-01". That's, in general, a different instant.

Categories