Dates before January 1st, 1970 - java

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

Related

Add 30 days in future from current epoch time Java

I am getting the current time in epoch. How can I add 1 month in future?
Date date = new Date();
int epoch = date.getTime();
Datatype for epoch - integer($int64)
To be precise: I want to add 30 days from current time.
I am using a tool that allows Groovy and Java code to be embedded. I used Date class because I can easily import java.text.DateFormat; and import java.text.SimpleDateFormat;. The tool that I have doesn't support Instant.
Since Java 8, use java.time for time usage
As epoch seconds, adding 30 days:
Instant.now().plus(30, ChronoUnit.DAYS).getEpochSecond()
As epoch milliseconds, adding 30 days:
Instant.now().plus(30, ChronoUnit.DAYS).toEpochMilli()
You don’t want to use Date, use date time API.
Instant.now().plus(30, ChronoUnit.DAYS)
Here's how I'd do it:
Calendar calendar = Calendar.getInstance();
calendar.add(Calendar.DATE, 30);
long epoch = calendar.getTimeInMillis();
System.out.println(epoch);
Result:
1606785580218
This is milliseconds. You can divide by 1000 to get the version in seconds. NOTE: The seconds version will fit in an int whereas the milliseconds version requires a long. So it's OK to do this if you want the seconds version in an int:
long epoch = ...
int epochSeconds = (int)(epoch / 1000);
BTW, Unix time (Epoch time, POSIX time) is defined as the number of seconds since 1 January 1970 UTC. Some systems will return the value in milliseconds to provide more accuracy, but such a value is officially a fractional Epoch time multiplied by 1000.
So far all answers are wrong.
That's because what you want is impossible.
You're mixing entirely incompatible concepts. You're asking to add 1 entity that is devoid of timezone and political meaning ('epoch-millis', which explicitly means: No timezone info!) with a concept that cannot be nailed down as meaning anything particular unless you supply timezone and era.
You cannot add a month to an epoch milli. Not because java doesn't let you, or because it is hard to program. You can't do it for the same reason you cannot point at the corner in a circle. It's literally impossible, by definition.
'epoch millis' are a concept that is fundamentally about a moment in time. Things like 'when the sun flared up'. "When I clapped my hands together just now". This concept is best represented in java by an instance of java.time.Instant. It is also represented by a java.util.Date, which is funny, because this is nothing like a Date, and indeed, j.u.Date is an utterly stupid name, and the authors have belatedly realized this, which is why (almost) all of the methods it has are marked #Deprecated with a note describing that Date's very name is a total lie. j.u.Date does not represent dates.
A month, that's an entirely different can of worms. There's nothing solid about a month. It could be 28 days. 30 days. 31 days. 30 days and an extra second tossed in. It could be a month that doesn't even exist, or is only 11 days (when political areas switch timezones, you can get some really bizarre things happening).
So, how do you add 'a month' to any instant in time?
You can't. It's not possible. You'd have no idea what to add, because there is no way to figure out if it's 28 days, 29, 30, 31, let alone leap seconds and era weirdness (recently, samoa switched to the other side of the dateline, and as a consequence, their december was only 30 days. The famous 'october revolution' that introduced communism to russia happened in november, at least as far as the entire world (except the russians) were concerned, because only the russians were on the julian calendar where it was still october. As part of the whole 'communism will take over the world!' scheme one of the very first things they did was get on the gregorian same as the rest of the world, and as a consequence, this date does not exist, AT ALL, in russian history: 1 through 13 feb 1918. They just. . were skipped. One day you wake up in moscow, walk outside, ask somebody: Hey, what date is it (though probably in russian), and they say: Why, 31st of January, comrade. Next day you repeat that exercise and now it is February 19th. So, february 1918 in russia was 15 days long.
See why 'please add 1 month' is just not a thing that could possibly be done unless you tell me when and where? If you tell me 'in russia', then I still don't know if I add 15, or 31, or 30, or 29, or 28. If you tell me 'Februari, in 1918', well, in the rest of the world, februari was 28 days. Only in russia it was 15.
Now, adding 'a month' to some human-oriented date/time construct, such as 'well, right now, in amsterdam', ah, that works: "THIS month, the month it is right now, in amsterdam", that is a question that has an answer. But, 'epoch millis' is java-ese for: "An instant in time, devoid of any and all geographical information", and by missing geo info it is also impossible to know when that is relative to any timezone, and therefore, utterly impossible.
So, what CAN you do? Well, many things, but first you need to figure out what you want to do, and only then can somebody tell you how to do it:
I just want to add what feels like an average month, and end up with epoch-millis. Okay, then just add 2.629.800.000, which is a rough estimate (that's about 30.4375 days, which is roughly the average length of a month. I have no idea what possible purpose this would serve, but it's surely a better plan than adding 30 days, or 31 days, or 28 days.
I want to first translate this epoch-millis into a time as humans would say it (in turns of year, month, day, hour, minute, and second), and then just increment the month value by 1, and leave it at that, in e.g. a ZonedDateTime object. Okay, then first figure out which timezone you want, then turn your epoch-millis into a ZonedDateTime, and THEN we've arrived at a point where 'add a month to this please' even makes sense, so now we can do that: .plusMonths(1), voila.
Same as previous, but then convert that back to epoch millis. Okay, well, do the same thing, and call .toInstant() at the end, and toEpochMillis() on that.
Most other ideas boil down to: Your question makes no sense and cannot be answered.
NB: The above all use the java.time packages. All other options (java.util.Date and java.util.Calendar are broken and unwieldy; generally attempting to do this or any other date-related job in those APIs will either be impossible, will give wrong answers, or there is a way but it is hard to figure out how and the resulting code will be hard to maintain and hard to follow. Why would you voluntarily punch yourself in the face? Why would you voluntary use crap APIs? Don't do that.

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)));

What is the best way to save epoch time in 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.

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.

PHP DateTime to Java Date

I have a PHP web service sending JSON responses back to my Java client. One of the fields is a DateTime value. However, I'm having problems translating the serialized PHP Date/Time to a Java Date.
For example, here is a date stored in my database:
2011-12-07 15:03:01
Here is how it's encoded in the JSON response:
1323288181
I suspected this would be the milliseconds since the Unix epoch, but when I construct a Java Date with that given value, the date turns out to be the following:
Fri Jan 16 01:34:48 CST 1970
Obviously it's not milliseconds since January 1, 1970 at midnight.
How do I go about doing this?
Looks like that's seconds since the Unix epoch - so just multiply your value by 1000 when passing it to the Date constructor.
Note that Date.toString() will always use the system time zone, but a Date really represents an instant in time, so it doesn't have a time zone.
If you're doing anything significant with dates and times, I'd thoroughly recommend using Joda Time instead of the classes in java.util.
I think it is a unixtimestamp. use this online convertor: http://www.onlineconversion.com/unix_time.htm
and here are examples how to convert it (in java):
http://www.epochconverter.com/
I am using
1970-01-01T00:00:00Z
as date time format in JSON,
then I make sure both sides parse it correctly

Categories

Resources