java.time.DateTimeException: Invalid value for Year (valid values -999999999 - 999999999) - java

I am getting this exception when I am trying to convert epochTime to LocalDate where:
1) Date : 2017-05-05 10:08:52.0
2) corresponding epoch :1493959132000
LocalDate lastUpdatedDate = LocalDate.ofEpochDay(1493959132000);
Exception :
java.time.DateTimeException: Invalid value for Year (valid values -999999999 - 999999999): 4090323145
at java.time.temporal.ValueRange.checkValidIntValue(ValueRange.java:330)
at java.time.temporal.ChronoField.checkValidIntValue(ChronoField.java:722)
at java.time.LocalDate.ofEpochDay(LocalDate.java:341)
I understand that the sourcecode of java.time.LocalDate gives a prior warning of this exception at https://docs.oracle.com/javase/8/docs/api/java/time/LocalDate.html#ofEpochDay-long-
What does this actually mean and when does it come?

Here's javadoc of ofEpochDay, this is what it says:
This returns a LocalDate with the specified epoch-day. The EPOCH_DAY
is a simple incrementing count of days where day 0 is 1970-01-01.
Negative numbers represent earlier days.
So, it expects the argument to be number of days since 1970-01-01. As the value you are passing is not valid, it throws the Exception.
Now, coming to your use case, if you want to convert epoch time to localdate then you need to use ofEpochMilli method of Instant class, e.g.:
LocalDate localDate =
Instant.ofEpochMilli(1493959132000l).atZone(ZoneId.systemDefault()).toLocalDate();
System.out.println(localDate);
Here's javadoc for Instant class.
Update
Alternatively, you can convert the timestamp into number of days since 1970-01-01 and pass it to ofEpochDay() method, e.g.:
LocalDate localDate = LocalDate.ofEpochDay(1493959132000l/(1000 * 60 *60 * 24));
System.out.println(localDate);

If you think about it, it doesn't make sense convert epoch seconds to local dates. At a specific moment in time you still need a location/time zone to determine which side of the date demarcation line you're on.
The epoch you mention is Fri, 05 May 2017 04:38:52 UTC. If you're in Greenwhich the LocalDate would be May 5th but if you're on the US West Coast it's still May 4th. Here's a list converting that epoch to different time zones
Instant.ofEpochMilli(1493959132000L).atZone(ZoneOffset.UTC).toLocalDate() //2017-05-05
Instant.ofEpochMilli(1493959132000L).atZone(ZoneId.of("America/Chicago")).toLocalDate() //2017-05-04
Therefore the argument asks for the amount of epoch days to convert to a local date.
LocalDate.ofEpochDay(17291) //2017-05-05

You are using the timeInMillis as the value instead of number of days. You could use the Duration class to calculate the number of days.
Duration duration = Duration.ofMillis(1493959132000);
long days = duration.toDays();
LocalDate lastUpdatedDate = LocalDate.ofEpochDay(days);

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

Java: Compare Date.getTime with a different date [duplicate]

This question already has answers here:
How to convert date time from one time zone to another time zone
(5 answers)
Closed 7 years ago.
There is the date date1 given with the format YY-MM-dd hh:mm:ss.SSS
I want to compare
date1.getTime()
with one retrieved by doing
new Date().getTime()
There is
SimpleDateFormat sf = new SimpleDateFormat("YY-MM-dd hh:mm:ss.SSS");
Date date1 = sf.parse(date1AsString);
...
compare date1.getTime() with new Date().getTime();
How can I bring these two dates to a common 'timezone' to compare them?
How can I obtain date1 to be on the same 'time length' as new Date()? I want to have the same timezone...
Thanks
From the javadoc of Date
The class Date represents a specific instant in time, with millisecond precision.
An instance in time is agnostic of our definition of time enhanced with time zones. Right now is the same for you and me, regardless of the fact that we are (potentially) in different time zones.
What adds the notion of a time zone is the DateFormat
The date is represented as a Date object or as the milliseconds since January 1, 1970, 00:00:00 GMT.
When you invoke Date#getTime(), you get back
the number of milliseconds since January 1, 1970, 00:00:00 GMT represented by this Date object.
This is something you can use to compare Date objects since they have the same root. Similarly, the compareTo will return
the value 0 if the argument Date is equal to this Date; a value
less than 0 if this Date is before the Date argument; and a value
greater than 0 if this Date is after the Date argument.
You cannot compare two dates if their timezone information is unknown.
For example if your date1AsString variable is simply 2014-12-16 16:00:00 then you cannot tell if it is greater than or less than 2014-12-16 20:00:00+0000.
It looks like first date is 4 hours less than second one; but if someone adds that the first date is Pacific Time (UTC-0800) then it would actually be 4 hours more than the second date (2014-12-16 16:00:00-0800 = 2014-12-17 00:00:00+0000).
So, if date1AsString has an unknown timezone then you cannot convert it to UTC or anything else for comparison.
getTime() Returns the number of milliseconds since January 1, 1970, 00:00 :00. You will want to compare the two longs, roughly like so:
long time = new Date().getTime();
long time2 = date1.getTime();
if(time>time2)
System.out.println(String.format("time is greater than time2 by %d", time-time2)
else
System.out.println(String.format("time2 is greater than time by %d", time2-time)
if you know Timezone
date1.setTime(date1.getTime()+/-(3600000*hours)) to convert, if date1 time is GMT to go to GMT+2 hours must be 2 and sing must be +
Typically any server environment is going to be using GMT so you wont have to worry about the timezone when comparing dates, only when formatting the value to be display to users.
You can compare two dates like so:
SimpleDateFormat sf = new SimpleDateFormat("YY-MM-dd hh:mm:ss.SSS");
Date date1 = sf.parse(date1AsString);
boolean isBefore = date1.before(new Date());
boolean isAfter = date1.after(new Date());
Alternatively, you can compare the numeric values of the unix time to get the same result:
...
boolean isBefore = date1.getTime() < new Date().getTime();
boolean isAfter = date1.getTime() > new Date().getTime();
The Date Class has methods like before(date) and after(date). You should take a look into the Date Class.
So I think what you are looking for is to set the time zone of the SimpleDateFormat:
sf.setTimeZone(TimeZone.getTimeZone("EST"));

Having problems on getting actual time in UTC Android

I am trying to get the the day and time in UTC as milliseconds but repeatedly get the same problem. The result should be something like '63530139420000' but each time the value '1394547490884' is returned.
To get the date and time in UTC I use the following method:
long dateutc = System.currentTimeMillis();
Can anyone tell me what is the problem?
You can use this.
DateFormat df = DateFormat.getTimeInstance();
df.setTimeZone(TimeZone.getTimeZone("UTC"));
String dateutc = df.format(new Date());
Your code correctly gets the number of milliseconds since January 1, 1970 00:00:00 UTC.
Interestingly if you take the value your teacher has specified and divide by the number of milliseconds in a year you get 2014.5. So either your teacher doesn't know what currentTimeMillis() does or he wants milliseconds since year 0 (which doesn't make any sense to me).
To calculate number of milliseconds since a given date all you need to do is to create two date instances and subtract the milliseconds values from getTime().

Joda Time subtracting 24 hours from an instance of MutableDateTime, I would like to know why

I do not understand why MutableDateTime.setDate() is setting the time to "yesterday" (see the log timestamp hours - it is 20:28). Is this timezone related? Do I need to set something on the formatter?
I would expect that after calling setDate with "10/27/2010", the date would be the same as the parsed date 00:00 EDT 10/27/10, instead of 20:28 EDT 10/26/10. This is 24 hours ago from "now".
What am I missing here, or how should I edit the code to get the desired result? I am new to Joda Time, and would like to solve this mystery.
DateTimeFormatter dateFormatterJ = DateTimeFormat.forPattern("MM/dd/yyyy");
DateTimeFormatter timestampFormatJ = DateTimeFormat.forPattern("HH:mm zzz MM/dd/yy");
MutableDateTime startDate = new MutableDateTime();
log.info("parsed date " +
timestampFormatJ.print(dateFormatterJ.parseMutableDateTime(startDateString)));
startDate.setDate((dateFormatterJ.parseMutableDateTime(startDateString)));
log.info("startDate: " + timestampFormatJ.print(startDate));
In this case, startDateString is simply "10/27/2010".
here is the log output:
10-27 20:28:55 INFO parsed date: 00:00 EDT 10/27/10
10-27 20:28:55 INFO startDate: 20:28 EDT 10/26/10
Thanks
The simple answer would be, because the javadoc says so.
public void setDate(ReadableInstant
instant)
Set the date from another
instant. The time part of this object
will be unaffected.
Parameters:
instant - an instant to copy the date
from, time part ignored
Throws:
IllegalArgumentException - if the
object is invalidobject is invalid
When Joda says 'Date' it means the human meaning of the word Date. "The year-month-day portion of this value", not the logical equivalent of a java.util.Date. (the whole point of joda being to introduce some natural, sensible, semantics to handling date and time.)
EDIT:
To answer your 'how to fix' question, simply do:
MutableDateTime startDate = new MutableDateTime(dateFormatterJ.parseMutableDateTime(startDateString));
Or else manually zero out the time portions of course.
EDIT 2: Hmm, I apparently did not read carefully enough, this is only half of the answer. Will check.
EDIT 3: well this bugged me so much that I took a minute to look for it.
public void setDate(final ReadableInstant instant) {
long instantMillis = DateTimeUtils.getInstantMillis(instant);
Chronology instantChrono = DateTimeUtils.getInstantChronology(instant);
DateTimeZone zone = instantChrono.getZone();
if (zone != null) {
instantMillis = zone.getMillisKeepLocal(**DateTimeZone.UTC**, instantMillis);
}
setDate(instantMillis);
}
For some reason, it's rolling your absolute time forward into UTC before setting the date. So you give it 10/27/2010 00:00 EDT and it sets the absolute magnitude of time to the number of milliseconds that represent 10/27/2010 00:00 UTC, which of course is only 6 or 7 PM the day before. Then it finds the EDT date value of that to be 10/26.
Couldn't say if that's somehow intended or if it's a bug that's been there for 2 years or what.)
When parsing a string that does not contain a GMT offset or time-zone ID, you must do one of three things:
do nothing, and accept that the string is parsed in the default time zone
specify the time zone to parse in using withZone() on the formatter
use parseLocalDate() instead of parseMutableDateTime()
The last is the preferred solution, as it correctly parses the data that was actually input, which was a date without time, offset or zone.
Using parseLocalDate() in the test code correctly parses the date.

How to define the date format?

I have the int number 2455449 and I know that represents the date 09/09/2010. How can I define the date format wihch is used? I need to generate a new date in this format. It will be used for http requests. I suppose that is Julian but I'm not sure. I tried to convert this number to the date but it didn't return the right date of 09/09/2010. Probably I used a wrong SimpleDateFormat("mm/dd/yy") or Calendar.XXXX (e.g.Calendar.DAY_OF_YEAR)
var now = new Date();
now.format("m/dd/yy");
// Returns, e.g., 6/09/07
// Can also be used as a standalone function
dateFormat(now, "dddd, mmmm dS, yyyy, h:MM:ss TT");
// Saturday, June 9th, 2007, 5:46:21 PM
// You can use one of several named masks
now.format("isoDateTime");
// 2007-06-09T17:46:21
// ...Or add your own
dateFormat.masks.hammerTime = 'HH:MM! "Can\'t touch this!"';
now.format("hammerTime");
// 17:46! Can't touch this!
http://blog.stevenlevithan.com/archives/date-time-format
looks like an equation with unknown function.f(d,m,y)=D; Where d the day, m month,y year and D is int date. And without loss of generality we can assume that this mapping should be one to one i.e. every valid (d,m,y) combination should map to a unique positive integer (>=0) and every positive integer must represent a valid and unique (d,m,y) tuple.So the most obvious choice of function f (based on the property of dates) is number of days elapsed since the first day, which satisfies our conditions. so now we have boundary condition.f(d1,m1,y1)=0;
f(9,9,2010)= 2455449;where d1,m1,y1 represents the reference date like epoch in unix timestamp. Using the obvious function (see above), (d1,m1,y1) comes out to be (10 5 -4713). So the DatFormat used is number of days elapsed since 10th June 4713 B.C. Approximately.
It is a Julian day number, and it counts the number of days since January 1, 4713 BC Greenwich noon in the Julian proleptic calendar.
To convert from a JD to a unix time stamp:
unix_time_stamp = ( JD -2440587.5) * 86400
To convert from unix time stamp to JD:
JD = (unix_time_stamp / 86400) + 2440587.5
Note that JD is counted from the noon, not midnight. That's why it's .5 at the end of the addition.
Update If you want to use it in javascript (that uses milliseconds since the epoch)
function dateFromJulianDay(julian_day) {
return new Date( (julian_day - 2440587.5) * 86400000);
}
function dateToJulianDay(date) {
// date should be a javascript Date object
// or a variable with milliseconds since the unix epoch 1 jan 1970
return ( date / 86400000) + 2440587.5;
}
console.log(dateFromJulianDay(2455449));
console.log(dateToJulianDay(new Date(2010,9-1,9)));
Remember that the month in the Date constructor is 0-11, whats why I do -1 above.

Categories

Resources