What is the best way to save epoch time in Java? - java

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.

Related

Find out the difference between two dates represented by two Long epoch values

My need is that I have a value in Long, which represent the milliseconds value since epoch. I wish to find out the difference in the number of days between that day and the current day.
I am using Java8's DAYS.between(inputDate, currentDate)
For the currentDate I have used LocalDateTime currentDate = LocalDateTime.now();
But the issue I am facing is when I am converting the long value into java8 LocalDateTime. When I use
LocalDate date = Instant.ofEpochMilli(1490372528)
.atZone(ZoneId.systemDefault())
.toLocalDate();
The result is 1970-01-18 while when I enter the same value in https://www.epochconverter.com/ it gives Fri, 24 Mar 2017 16:22:08 GMT
Why is this discrepancy there? How to effectively get a java8 date from a long value to use in DAYS.between()?
You have to decide. Either, your number is “milliseconds value since epoch”, as you stated in your question, or it is “number of seconds that have elapsed since January 1, 1970”, as stated (and used) on the linked web site.
If it is truly “milliseconds since epoch”, you can use
System.out.println(Instant.ofEpochMilli(1490372528).until(Instant.now(), ChronoUnit.DAYS));
to print the number of days, which is, by the way, not simpler than the pre-Java 8 code
System.out.println(TimeUnit.MILLISECONDS.toDays(System.currentTimeMillis()-1490372528));
If your number actually is “seconds since epoch”, you have little to change in your code
System.out.println(Instant.ofEpochSecond(1490372528).until(Instant.now(),ChronoUnit.DAYS));
which is equivalent to
System.out.println(ChronoUnit.DAYS.between(Instant.ofEpochSecond(1490372528),Instant.now()));
as you mentioned DAYS.between explicitly. It will just delegate to the until method used above. The equivalent pre-Java 8 code would be slightly more complicated
System.out.println(TimeUnit.MILLISECONDS.toDays(
System.currentTimeMillis()-TimeUnit.SECONDS.toMillis(1490372528)));

C# Ticks convert to java util date; date is 5 hours behind why?

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.

Get time of a calendar in nanoseconds

Since the Java doc tell me, not to use System.currentTimeMillis for comparison, I started using System.nanoTime which is fine.
But I ran into some problems, I have to compare events which are in the past.
Calendar cal = Calendar.getInstance();
cal.add(Calendar.DAY_OF_MONTH, xyz);
cal.getTimeMillis();
works fine to get the time in milliseconds, but converting it to nanoseconds (by multiplying it with 1000000) is far to inaccurate.
How can I get time of a event in the past in milliseconds?
The Calendar class in Java doesn't contain nanosecond information. So you can't get that.
You need to store the nanoseconds as long for the event you want to compare later if you need that detail.: you can't do that too, the nanoTime() is not a representation of current time, but you may still store that to evaluate elapsed time of old processes.
What data type are you using for the multiplication by 1,000,000 ? Perhaps you should use a BigDecimal, which would be accurate enough for you.

Dates before January 1st, 1970

The getTime() fetches the time in millis for a certain Date. Can this be used reliably for dates say in the 18th century. We use the millis and store it in a string variable for future comparison. Is there a limit on how far in the past that this could be used?
I would highly recommend you take a look at JodaTime if you are doing date/time comparisons of the distant past. Or actually any sort of date/time comparisons and calculations. It is a great library!
Don't rely on getTime() for what you want to do. At least consider using Java's Calendar/GregorianCalendar. But personally, I'd suggest using JodaTime.
Of course, long is signed and for example 1.1.1701 is -8 488 782 000 000.
Returns the number of milliseconds since January 1, 1970, 00:00:00 GMT represented by this Date object
Better to go for Calendar OR Jodatime

Best Duration type in Java or .Net

I have seen way to many places where a method takes a long or an int to represent durations in either nanoseconds, milliseconds (most common), seconds and even days. This is a good place to look for errors, too.
The problem is also quite complex once you realize that you can mean for the duration to be a certain number of seconds, or an interval that fits the human perception of time better, so that a duration of 24 hours is always going to be the next day at the same "wall-clock" time. Or that a year is either 365 or 366 days depending on the date, so that a year from 28th of February is always going to be the 28th of February.
Why is there no distinct type to represent this? I have found none in either Java or .net
In .Net you can use the TimeSpan structure to represent a length of time.
For Java, take a look at Joda (an intuitive and consistent date/time library) and its Duration and Period classes. DateTime objects can handle addition and manipulation via these objects.
(answer changed to reflect the comments below re. the Period class)
It's not an easy problem. Maybe Joda-Time would be a useful library for you. It has a Duration class that can do what you are asking for.

Categories

Resources