Java ZonedDateTime to Instant conversion - java

I am planning to convert ZonedDateTime to instant as per the below logic.
Say, I am in PST timeZone and the current time is 11A.M. If I convert now( no daylight saving as of today March 04 2018) and the toInstant will be 7P.M.
For the same 11 A.M, the toInstant will return 6 P.M as of April 04 2018 as daylight saving will be observed.
So, The below code returns correctly.
ZonedDateTime dateTime = ZonedDateTime.now(); --->>> March 04th 2018 at 11 A.M PST
dateTime.plusMonths(1).toInstant(); -->> returns April 04th 2018 at 6 PM PST as daylight saving will be observed
But,
The result will be different if i convert to Instant and then add a month.
Instant dateTime = ZonedDateTime.now().toInstant(); --->>> March 04th 2018 at 7 P.M UTC
dateTime.plus(1,ChronoUnit.MONTHS).toInstant(); -->> returns April 04th 2018 at 7 PM UTC ( but the actual time should be 6 PM UTC ).
This is ok, as we already converted to UTC and it just adds from there.
Hence, To include the daylight saving time, I need to add days or months or years .... to ZonedDateTime and then convert to Instant.
ZonedDateTime dateTime = ZonedDateTime.now(); ---> March 04th 2018 at 11A.M
dateTime.plusDays(10).toInstant(); ---> March 14th 2018 at 6P.M
dateTime.plusMonths(1).toInstant(); ---> April 04th 2018 at 6P.M
The above code works as expected. But the below one is not returning 6P.M, But it returns 7P.M.
dateTime.plusSeconds(org.joda.time.Period.days(1).multipliedBy(10).toStandardSeconds().getSeconds())
.toInstant()) --> ---> March 14th 2018 at 7P.M
Not sure, what is wrong with this and how to make it work with seconds.

The cause is found in the documentation for the ZonedDateTime class. For the method plusDays we see this in the method documentation:
This operates on the local time-line, adding days to the local date-time. This is then converted back to a ZonedDateTime, using the zone ID to obtain the offset.
When converting back to ZonedDateTime, if the local date-time is in an overlap, then the offset will be retained if possible, otherwise the earlier offset will be used. If in a gap, the local date-time will be adjusted forward by the length of the gap.
However, in the documentation for the plusSeconds method we see this:
This operates on the instant time-line, such that adding one second will always be a duration of one second later. This may cause the local date-time to change by an amount other than one second. Note that this is a different approach to that used by days, months and years.
So the two methods are designed to behave differently, and you need to consider this when choosing which method to use to suit your purpose.

As I understand your requirement you have a number of minutes or hours to add to your time, for example
long minutesToAdd = Duration.ofDays(10).toMinutes();
I am using java.time since I haven’t got experience with Joda-Time. Maybe you can translate my idea to Joda-Time if you wish.
As I further understand, the result of adding the above minutes should not be a point in time that number of minutes later. Instead it should work the same as adding 10 days. So if it’s 9 PM in California, you want 9 PM in California 10 days later. I suggest you solve this by converting to LocalDateTime before adding the minutes or hours, and then convert back to ZonedDateTime afterwards.
ZonedDateTime now = ZonedDateTime.now(ZoneId.of("America/Los_Angeles"));
System.out.println(now);
System.out.println(now.toInstant());
Instant inTenDays = now.toLocalDateTime()
.plusMinutes(minutesToAdd)
.atZone(now.getZone())
.toInstant();
System.out.println(inTenDays);
This just printed
2018-03-04T21:16:19.187690-08:00[America/Los_Angeles]
2018-03-05T05:16:19.187690Z
2018-03-15T04:16:19.187690Z
Since summer time (DST) is in effect on March 15 (it is from March 11 this year), you don’t get the same hour-of-day in UTC, but instead the same hour-of-day in your time zone.

Related

How to set correct time with AM PM with Calendar object?

Simple question why the result is like the following for this code:
Calendar cal2 = Calendar.getInstance();
cal2.set(Calendar.HOUR, 12);
cal2.set(Calendar.AM_PM, Calendar.PM);
System.out.println(cal2.getTime().toString()); // Wed Jan 13 00:11:08 EET 2021
cal2.set(Calendar.AM_PM, Calendar.PM);
System.out.println(cal2.getTime().toString()); // Wed Jan 13 12:11:08 EET 2021
Calendar cal = Calendar.getInstance();
cal.set(Calendar.HOUR, 12);
cal.set(Calendar.AM_PM, Calendar.AM);
System.out.println(cal.getTime().toString()); // Tue Jan 12 12:11:08 EET 2021
cal.set(Calendar.AM_PM, Calendar.AM);
System.out.println(cal.getTime().toString()); // Tue Jan 12 00:11:08 EET 2021
The first looks like it is 12 at midnight not afternoon.
The third one looks like it is 12 afternoon, not midnight
Why setting calendar AM or PM multiple times change the result?
How to set the time correctly?
Calendar is very confusing
You are so far from the first being confused about how the Calendar class works. Fortunately the class is also long outdated. You should not use it.
Why setting calendar AM or PM multiple times change the result? …
To answer your question as asked, Andi80 is correct in the other answer and the comments to it: HOUR goes from 0 through 11. The documentation says about HOUR:
Field number for get and set indicating the hour of the morning or
afternoon. HOUR is used for the 12-hour clock (0 - 11). Noon and
midnight are represented by 0, not by 12. E.g., at 10:04:15.250 PM the
HOUR is 10.
When you first set hour to 12 and AM/PM to PM, one should have expected an exception because the hour value is out of range. But no, a Calendar object with default settings doesn’t give you that. Instead it sets the time to 0 AM the following day; Jan 13 when you ran the code on Jan 12. By Calendar logic hour 12 is the hour that comes after hour 11.
When you set PM again, Calendar takes off from the time you had already got, which is in AM, and changes it into PM, so you get 12:11:08, still on Jan 13, the following day.
Why does it calculate the time twice? Not once and not three times when you do three calls to set()? It’s another confusing trait of Calendar. It calculates the time when you call getTime() (and some designated other methods). At that point it picks up all the changes from the calls to set() up to that point and combines them to the best of its abilities, discarding some if there are conflicts, using rules that no person in their right mind will want to understand.
The case for AM is similar, so I leave the details to the reader.
java.time
… How to set the time correctly?
I recommend that you use java.time, the modern Java date and time API, for your time work. If you just want 12 noon or 12 midnight, they are built in as constants:
LocalTime t12Noon = LocalTime.NOON;
System.out.println(t12Noon);
LocalTime t12Midnight = LocalTime.MIDNIGHT;
System.out.println(t12Midnight);
Output is:
12:00
00:00
A LocalTime is a time of day without a date.
If you have already got a time and only want to adjust the hour and AM/PM, use with():
LocalTime t12Noon = LocalTime.now(ZoneId.systemDefault())
.with(ChronoField.CLOCK_HOUR_OF_AMPM, 12)
.with(ChronoField.AMPM_OF_DAY, 1); // 1 = PM
System.out.println(t12Noon);
LocalTime t12Midnight = LocalTime.now(ZoneId.systemDefault())
.with(ChronoField.CLOCK_HOUR_OF_AMPM, 12)
.with(ChronoField.AMPM_OF_DAY, 0); // 0 = AM
System.out.println(t12Midnight);
12:47:00.665155
00:47:00.669248
If you need the date too, use ZonedDateTime or another appropriate class. All of the date-time classes of java.time that include time of day have the same with method, so the code will be the same.
If you indispensably need a Calendar object for a legacy API that you cannot afford to upgrade to java.time just now, use a ZonedDateTIme from java.time for your time math. Then use GregorianCalendar.from(ZoendDateTIme) for the conversion to a Calendar object.
Links
Documentation of Calendar.HOUR
Oracle tutorial: Date Time explaining how to use java.time.
Calendar.HOUR takes inputs in range 0-11. It will wrap around the 12 to a 0.
Use Calendar.HOUR_OF_DAY instead to use values from 0-23.

Convert Unix time stamp to Date [duplicate]

This question already has answers here:
Unix epoch time to Java Date object
(7 answers)
convert millisecond to Joda Date Time or for zone 0000
(3 answers)
Closed 4 years ago.
I have Long value 1282680754000 where if I check this value in https://www.epochconverter.com/ it gives me Tuesday, August 24, 2010 8:12:34 PM
But if I use new DateTime(1282680754000).toDate() I get Wed Aug 25 01:42:34 IST 2010 (It is adding +5.30 hour)
How to get Tuesday, August 24, 2010 8:12:34 PM for 1282680754000 in java
Just use
Instant.ofEpochMilli(1_282_680_754_000L)
or
Instant.ofEpochMilli(1_282_680_754_000L).atOffset(ZoneOffset.UTC)
(using java.time, the modern Java date and time API; you may consider it the successor of Joda-Time).
The latter will give you an OffsetDateTime, which you can then format into youe desired format.
What went wrong in your code?
Your code is correct. You got the correct Date. The only things are:
For most purposes you shouldn’t want a java.util.Date. That class is long outdated and has design problems, which was the major background for development of Joda-Time and later java.time.
Your Date was printed in your local time (IST, probably India Standard Time or Asia/Kolkata) where you expected UTC. A Date has got neither time zone nor offset in it. When you print it, its toString method grabs your JVM’s time zone setting and renders the time in this time zone — in your case in IST. This behaviour surprises many.
Link: All about java.util.Date on Jon Skeet’s coding blog
String result = DateTimeFormatter.ofPattern("EEEE, MMMM dd, yyyy h:mm:ss a")
.withZone(ZoneId.of("UTC"))
.toFormat()
.format(Instant.ofEpochMilli(1282680754000L));
System.out.println(result); // Tuesday, August 24, 2010 8:12:34 PM
Omit the toDate, you are converting it to a Date object, which its toString method uses your operating system default time zone to print its value (you can see the IST in your question).
Just for reference examine the follows:
public static void main(String[] args) {
DateTime dateTime = new DateTime(1282680754000L, DateTimeZone.forID("GMT"));
System.out.println(dateTime.toDate().toGMTString());
}
24 Aug 2010 20:12:34 GMT
against (my default time zone is IDT):
public static void main(String[] args) {
DateTime dateTime = new DateTime(1282680754000L,DateTimeZone.forID("GMT"));
System.out.println(dateTime.toDate());
}
Tue Aug 24 23:12:34 IDT 2010

How to handle CST to CDT or vice versa using XMLGregorianCalendar

I had the below issue During daylight change CST-CDT reset.
Am getting the Input from Was8.5 server 2018-03-11-05.00 (UTC-5) as expected, but when it comes to WAS7 server, the below method returns Sun Mar 10 00.00.00 CST 2018 instead of Sun Mar 11 00.00.00 CDT 2018
/*
* Converts XMLGregorianCalendar to java.util.Date
*/
public static Date toDate(XMLGregorianCalendar calendar){
if(calendar == null) {
return null;
}
return calendar.toGregorianCalendar().getTime();
}
I know the server date/timezone reset didn’t take place properly, but in case if I want to get right Time when CST to CDT change or vise versa. How can I rewrite the code to convert XMLGregorianCalendar to java.util.Date in Java?
Something like,
If incoming request was CST(UTC-6), the toDate(XMLGregorianCalendar calendar) returns CDT (UTC-5). then I want toDate() should return CST (UTC-6).
the same way,
If incoming request was CDT(UTC-5), the toDate(XMLGregorianCalendar calendar) returns CST(UTC-6). then i want toDate() should return CDT(UTC-5).
java.util.Date doesn't have a timezone. It just have a long value that represents the number of milliseconds since unix epoch.
What you see (Sun Mar 10 00.00.00 CST 2018) is the result of toString() method, and it uses the JVM default timezone to convert the long value to a date and time in that timezone. See this article for more details:
https://codeblog.jonskeet.uk/2017/04/23/all-about-java-util-date/
Anyway, one way to really know what's happening is to check this long value:
long millis = calendar.toGregorianCalendar().getTimeInMillis();
And then you can print this value in UTC:
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss XXX");
sdf.setTimeZone(TimeZone.getTimeZone("UTC"));
System.out.println(sdf.format(new Date(millis)));
Or, if you use Java 8:
System.out.println(Instant.ofEpochMilli(millis));
This will tell you the UTC instant that the Date corresponds to, so you can debug your code a little better than relying on Date::toString() method, which is confusing and misleading.
Regarding your main issue, I've tried to reproduce (I'm using Java 8 because it's easier to manipulate than using Date). First I created a date/time corresponding to 2018-03-11 in UTC-05:00, and I assumed the time to be midnight:
// March 11th 2018, midnight, UTC-05:00
OffsetDateTime odt = OffsetDateTime.parse("2018-03-11T00:00-05:00");
Then I converted this to America/Chicago timezone, which is a zone that uses CST/CDT:
// get the same instant in Central Time
ZonedDateTime zdt = odt.atZoneSameInstant(ZoneId.of("America/Chicago"));
Then I printed this:
// print the date/time with timezone abbreviation
DateTimeFormatter fmt = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm xxx z", Locale.US);
System.out.println(zdt.format(fmt)); // 2018-03-10 23:00 -06:00 CST
Note that the result is 2018-03-10 23:00 -06:00 CST: March 10th in UTC-06:00.
That's because in 2018, Daylight Saving Time starts only at 2 AM of March 11th. At midnight, DST has not started yet, so the offset is still UTC-06:00.
Anyway, your conversion code is correct, because Date just represents a point in time (a count of elapsed time since epoch) and doesn't have timezone attached to it. Perhaps the problem lies somewhere, and checking the millis value might help you to understand what's going on (my guess is that XmlGregorianCalendar sets the time to midnight when it's not present, which would explain the result of Sun Mar 10 00.00.00 CST 2018).
If that helps, the exact UTC instant where DST transition occurs (March 11th 2018 at 2 AM in UTC-06:00) corresponds to the millis value 1520755200000. If your dates in March 2018 have a value lower than that, it means they're before DST starts, and they'll be in CST.
My first suggestion is that you don’t need what you are asking for. As I see it, you’ve got a date and a UTC offset, and I don’t really see that the offset adds any useful information. Just take the date. I believe what has happened was that a point in time after the transition to summer time on March 11 was stripped of the time-of-day, but the UTC offset was kept for whatever reason or maybe for no reason at all. When giving the time at start of day (00:00), the offset disagrees with your time zone of America/Chicago (or Central Time Zone, but the ID in region/city format is unambiguous and recommended).
And don’t use java.util.Date for your date. That class is long outdated. Today we have so much better in java.time, the modern Java date and time API. Furthermore its LocalDate class is better suited for a date without time-of-day because this is exactly what it is, while a Date is really a point a in time, that is, a whole different story. Depending on taste conversion from XMLGregorianCalendar can happen in two ways.
The direct way
return LocalDate.of(calendar.getYear(), calendar.getMonth(), calendar.getDay());
With your XMLGregorianCalendar of 2018-03-11-05:00 the result is a LocalDate of 2018-03-11.
The indirect way via GregorianCalendar and ZonedDateTime:
return calendar.toGregorianCalendar().toZonedDateTime().toLocalDate();
The result is the same. The advantage of the latter is you don’t need to concern yourself with the individual fields of year, month and day-of-month. Among other things this means you don’t risk putting them in the wrong order.
If you do insist on keeping the time zone or UTC offset, at least take the offset. Sun Mar 11 00.00.00 CDT 2018 doesn’t make sense because March 11 at 00:00 hours DST was not yet in effect (it began at 02:00). Such a non-existing time will just confuse everyone. Convert your calendar object to OffsetDateTime:
return calendar.toGregorianCalendar().toZonedDateTime().toOffsetDateTime();
Result: 2018-03-11T00:00-05:00. This point in time exists.:-)
Since your calendar comes from a foreign system, you will probably want to validate it since any field may be undefined and return DatatypeConstants.FIELD_UNDEFINED. When using LocalDate.of(), you may decide that its argument validation is enough since it will object to DatatypeConstants.FIELD_UNDEFINED being passed as an argument. toGregorianCalendar() on the other hand will tacitly use default values, so when using it I would consider validation indispensable.
What went wrong in your code?
I ran your code, and similarly to iolus (see the other answer) I got Sat Mar 10 23:00:00 CST 2018. This the correct point in time. As iolus also explained, this is Date.toString rendering the point in time this way. The Date object itself doesn’t have a time zone or UTC offset in it. So I should say that your code was correct. It was just you getting confused by the toString method. Many have been before you, and the good solution is to avoid the Date class completely. Also I would think that your observations have nothing to do with any difference between WAS 7 and WAS 8.5.

How to create a Date object, using UTC, at a specific time in the past?

Is it possible to create a java.util.Date object that is guaranteed to be UTC and at a specific time in the past, like an hour ago or a day ago, and is this a good idea?
I have reviewed the Stack Overflow question
get date as of 4 hours ago and its answers. But I want to avoid having to add more dependencies, like jodaTime, and the accepted answer uses System.currentTimeMillis() which would be the local timezone, would it not?
As discussed vividly in the comments, the recommendation is to use the java.time package. The easy solution:
Instant fourHoursAgo = Instant.now().minus(Duration.ofHours(4));
System.out.println(fourHoursAgo);
This just printed
2018-01-31T14:57:44.667255Z
Since UTC time is now 18:58, the output is what you asked for. The Instant itself is offset neutral. Its toString delivers time in UTC, but there was no mention of UTC in producing the Instant, so whether it gives you what you want, I am not sure. I will give you a result that is explicitly in UTC later.
But first, if you do need a java.util.Date, typically for a legacy API that you cannot change, the conversion is easy:
Date oldfashionedDate = Date.from(fourHoursAgo);
System.out.println(oldfashionedDate);
On my computer in Europe/Copenhagen time zone this printed:
Wed Jan 31 15:57:44 CET 2018
Again, this agrees with the time four hours before running the snippet. And again, a Date doesn’t have a UTC offset in it. Only its toString method grabs my JVM’s time zone setting and uses it for generating the string, this does not affect the Date. See the Stack Overflow question, How to set time zone of a java.util.Date?, and its answers.
As promised, if you do need to represent not only the time but also the offset, use an OffsetDateTime:
OffsetDateTime fourHoursAgoInUtc = OffsetDateTime.now(ZoneOffset.UTC).minusHours(4);
System.out.println(fourHoursAgoInUtc);
This printed
2018-01-31T14:57:44.724147Z
Z at the end means offset zero from UTC or “Zulu time zone” (which isn’t a true time zone). The conversion to a Date is not much more complicated than before, but again, you will lose the offset information in the conversion:
Date oldfashionedDate = Date.from(fourHoursAgoInUtc.toInstant());
System.out.println(oldfashionedDate);
This printed:
Wed Jan 31 15:57:44 CET 2018
Link: Oracle tutorial explaining how to use java.time
You can achieve this using the java.time package, as follows:
LocalDateTime localDateTime = LocalDateTime.now(ZoneOffset.UTC).minusHours(4);
Date date = Date.from(localDateTime.atZone(ZoneOffset.UTC).toInstant());
Gives the following output:
2018-01-31T14:58:28.908
Wed Jan 31 20:28:28 IST 2018 //20:28:28 IST is 14:58:28 UTC
Which is correctly 4+5:30 hours behind my current time - Asia/Kolkata ZoneId.

Converting Long to Date in Java returns 1970

I have list with long values (for example: 1220227200, 1220832000, 1221436800...) which I downloaded from web service. I must convert it to Dates. Unfortunately this way, for example:
Date d = new Date(1220227200);
returns 1 Jan 1970. Anyone know another way to convert it correctly?
The Date constructor (click the link!) accepts the time as long in milliseconds, not seconds. You need to multiply it by 1000 and make sure that you supply it as long.
Date d = new Date(1220227200L * 1000);
This shows here
Sun Aug 31 20:00:00 GMT-04:00 2008
tl;dr
java.time.Instant // Represent a moment as seen in UTC. Internally, a count of nanoseconds since 1970-01-01T00:00Z.
.ofEpochSecond( 1_220_227_200L ) // Pass a count of whole seconds since the same epoch reference of 1970-01-01T00:00Z.
Know Your Data
People use various precisions in tracking time as a number since an epoch. So when you obtain some numbers to be interpreted as a count since an epoch, you must determine:
What epoch?Many epochs dates have been used in various systems. Commonly used is POSIX/Unix time, where the epoch is the first moment of 1970 in UTC. But you should not assume this epoch.
What precision?Are we talking seconds, milliseconds, microseconds, or nanoseconds since the epoch?
What time zone?Usually a count since epoch is in UTC/GMT time zone, that is, has no time zone offset at all. But sometimes, when involving inexperienced or date-time ignorant programmers, there may be an implied time zone.
In your case, as others noted, you seem to have been given seconds since the Unix epoch. But you are passing those seconds to a constructor that expects milliseconds. So the solution is to multiply by 1,000.
Lessons learned:
Determine, don't assume, the meaning of received data.
Read the doc.
Your Data
Your data seems to be in whole seconds. If we assume an epoch of the beginning of 1970, and if we assume UTC time zone, then 1,220,227,200 is the first moment of the first day of September 2008.
Joda-Time
The java.util.Date and .Calendar classes bundled with Java are notoriously troublesome. Avoid them. Use instead either the Joda-Time library or the new java.time package bundled in Java 8 (and inspired by Joda-Time).
Note that unlike j.u.Date, a DateTime in Joda-Time truly knows its own assigned time zone. So in the example Joda-Time 2.4 code seen below, note that we first parse the milliseconds using the default assumption of UTC. Then, secondly, we assign a time zone of Paris to adjust. Same moment in the timeline of the Universe, but different wall-clock time. For demonstration, we adjust again, to UTC. Almost always better to explicitly specify your desired/expected time zone rather than rely on an implicit default (often the cause of trouble in date-time work).
We need milliseconds to construct a DateTime. So take your input of seconds, and multiply by a thousand. Note that the result must be a 64-bit long as we would overflow a 32-bit int.
long input = 1_220_227_200L; // Note the "L" appended to long integer literals.
long milliseconds = ( input * 1_000L ); // Use a "long", not the usual "int". Note the appended "L".
Feed that count of milliseconds to constructor. That particular constructor assumes the count is from the Unix epoch of 1970. So adjust time zone as desired, after construction.
Use proper time zone names, a combination of continent and city/region. Never use 3 or 4 letter codes such as EST as they are neither standardized not unique.
DateTime dateTimeParis = new DateTime( milliseconds ).withZone( DateTimeZone.forID( "Europe/Paris" ) );
For demonstration, adjust the time zone again.
DateTime dateTimeUtc = dateTimeParis.withZone( DateTimeZone.UTC );
DateTime dateTimeMontréal = dateTimeParis.withZone( DateTimeZone.forID( "America/Montreal" ) );
Dump to console. Note how the date is different in Montréal, as the new day has begun in Europe but not yet in America.
System.out.println( "dateTimeParis: " + dateTimeParis );
System.out.println( "dateTimeUTC: " + dateTimeUtc );
System.out.println( "dateTimeMontréal: " + dateTimeMontréal );
When run.
dateTimeParis: 2008-09-01T02:00:00.000+02:00
dateTimeUTC: 2008-09-01T00:00:00.000Z
dateTimeMontréal: 2008-08-31T20:00:00.000-04:00
java.time
The makers of Joda-Time have asked us to migrate to its replacement, the java.time framework as soon as is convenient. While Joda-Time continues to be actively supported, all future development will be done on the java.time classes and their extensions in the ThreeTen-Extra project.
The java-time framework is defined by JSR 310 and built into Java 8 and later. The java.time classes have been back-ported to Java 6 & 7 on the ThreeTen-Backport project and to Android in the ThreeTenABP project.
An Instant is a moment on the timeline in UTC with a resolution of nanoseconds. Its epoch is the first moment of 1970 in UTC.
Instant instant = Instant.ofEpochSecond( 1_220_227_200L );
Apply an offset-from-UTC ZoneOffset to get an OffsetDateTime.
Better yet, if known, apply a time zone ZoneId to get a ZonedDateTime.
ZoneId zoneId = ZoneId.of( "America/Montreal" );
ZonedDateTime zdt = ZonedDateTime.ofInstant( instant , zoneId );
It looks like your longs are seconds, and not milliseconds. Date constructor takes time as millis, so
Date d = new Date(timeInSeconds * 1000);
Only set the time in mills on Calendar object
Calendar c = Calendar.getInstance();
c.setTimeInMillis(1385355600000l);
System.out.println(c.get(Calendar.YEAR));
System.out.println(c.get(Calendar.MONTH));
System.out.println(c.get(Calendar.DAY_OF_MONTH));
// get Date
System.out.println(c.getTime());
Those are probably timestamps in seconds and not in milliseconds which is required for the java new Date(long) constructor. Just multiply them by 1000 and you should be allright.
The long values, most likely, correspond to Epoch timestamps, and the values are:
1220227200 = Mon, 01 Sep 2008 00:00:00 GMT
1220832000 = Mon, 08 Sep 2008 00:00:00 GMT
1221436800 = Mon, 15 Sep 2008 00:00:00 GMT
One can convert these long values to java.util.Date, taking into account the fact java.util.Date uses millisecs – as previously hinted, but with some flaw - like this:
// note: enforcing long literals (L), without it the values would just be wrong.
Date date = new Date(1220227200L * 1000L);
Now, to display the date correctly, one can use java.text.DateFormat as illustrated hereafter:
DateFormat df = DateFormat.getDateTimeInstance(DateFormat.FULL, DateFormat.FULL);
df.setTimeZone(TimeZone.getTimeZone("UTC"));
System.out.println("Wrong date time value: " + date);
System.out.println("Correct date time value: " + df.format(date));
Below are the results of displaying the converted long value to java.util.Date without
using and using the DateFormat:
Date wrong (off by 2 hours): Mon Sep 01 02:00:00 CEST 2008
Correct date : Monday, 1 September 2008 00:00:00 o'clock UTC
Try this:
Calendar cal = Calendar.getInstance();
cal.setTimeInMillis(1220227200 * 1000);
System.out.println(cal.getTime());
Try this with adjusting the date format.
long longtime = 1212580300;
SimpleDateFormat dateFormat = new SimpleDateFormat("MMddyyHHmm");
Date date = (Date) dateFormat.parseObject(longtime + "");
System.out.println(date);
Note: Check for 24 hours or 12 hours cycle.
1220227200 corresponds to Jan 15 1980 (and indeed new Date(1220227200).toString() returns "Thu Jan 15 03:57:07 CET 1970"). If you pass a long value to a date, that is before 01/01/1970 it will in fact return a date of 01/01/1970. Make sure that your values are not in this situation (lower than 82800000).
New Date(number) returns a date that's number milliseconds after 1 Jan 1970. Odds are you date format isn't showing hours, minutes, and seconds for you to see that it's just a little bit after 1 Jan 1970.
You need to parse the date according to the correct parsing routing. I don't know what a 1220227200 is, but if it's seconds after 1 JAN 1970, then multiply it to yield milliseconds. If it is not, then convert it in some manner to milliseconds after 1970 (if you want to continue to use java.util.Date).
Works for me. You probably want to multiplz it with 1000, since what you get are the seconds from 1970 and you have to pass the milliseconds from jan 1 1970
Because 1220227200 ms = 338,952 hours.
java.util.Date has constructor new Date(Long milliseconds) - Allocates a Date object and initializes it to represent the specified number of milliseconds since the standard base time known as "the epoch", namely January 1, 1970, 00:00:00 GMT.
So, in your case just remember 1 sec = 1000 millisec

Categories