shree18
shree18

Reputation: 1469

java.util.Date class with different approach for same date gives different output

public static void main(String[] args) throws ParseException {
    // create a date
    Date date = new Date();
    long diff = date.getTime();
    Date date1 = new Date(2013, 10, 1, 11, 6);
    long diff1 = date1.getTime();
    System.out.println("date is 1-10-2013, " + diff + " have passed.");
    System.out.println("date is 1-10-2013, " + diff1 + " have passed.");
}

and the output is

date is 1-10-2013, 1380605909318 have passed.
date is 1-10-2013, 61341428160000 have passed.

Can anybody elaborate on the difference beween 1380605909318 and 61341428160000?

Upvotes: 6

Views: 390

Answers (8)

Basil Bourque
Basil Bourque

Reputation: 339193

tl;dr

ZonedDateTime
.of ( 
    LocalDate.of ( 2013, 10, 1 ) , 
    LocalTime.of ( 11, 6 ) , 
    ZoneId.of ( "America/Edmonton" )
)
.toInstant()
.toEpochMilli()

java.time

The Answer by Jon Skeet is correct. In addition:

  • You ignored the crucial issue of time zone.
  • In modern Java, we use the java.time classes only. Never use either Date class. In contrast to the legacy date-time classes, java.time uses sane numbering. So "2025" is the year 2025. Month 10 is October.

A date with time-of-day is inherently ambiguous. Do you mean that time in Tokyo Japan, that time in Toulouse France, or that time in Toledo Ohio US — three very different moments several hours apart.

ZonedDateTime

The ZonedDateTime class represents a moment, a point on the timeline, as seen through a particular time zone.

LocalDate ld = LocalDate.of ( 2013, 10, 1 ) ;
LocalTime lt = LocalTime.of ( 11, 6 ) ;
ZoneId z = ZoneId.of ( "Asia/Tokyo" ) ;
ZonedDateTime zdt = ZonedDateTime.of ( ld , lt , z ) ;

Instant

Extract an Instant object to adjust into UTC, an offset of zero hours-minutes-seconds ahead/behind the temporal meridian of UTC. This Instant object too is a moment, a point on the timeline. Our Instant object here is the very same point as our ZonedDateTime object — Two ways of viewing the same moment.

Instant instant = zdt.toInstant() ;

Interrogate that Instant object for a count of milliseconds since the epoch reference of first moment of 1970 in UTC, 1970-01-01T00:00Z.

long millis = instant.toEpochMilli() ;

Upvotes: 1

nik
nik

Reputation: 251

 @Deprecated
 public Date(int year,
                   int month,
                   int date,
                   int hrs,
                   int min)

Deprecated. As of JDK version 1.1, replaced by Calendar.set(year + 1900, month, date, hrs, min) or GregorianCalendar(year + 1900, month, date, hrs, min).

Allocates a Date object and initializes it so that it represents the instant at the start of the minute specified by the year, month, date, hrs, and min arguments, in the local time zone.

Parameters:
    year - the year minus 1900.
    month - the month between 0-11.
    date - the day of the month between 1-31.
    hrs - the hours between 0-23.
    min - the minutes between 0-59.

So if you want to get the same or very near results you have to use as following

Date date1 = new Date(113, 9, 1, 11, 6);

Upvotes: 0

Scary Wombat
Scary Wombat

Reputation: 44844

try

System.out.println("date is 1-10-2013, " + diff + " have passed.");
System.out.println("date is " + date1.toString() + diff1 + " have passed.");  

and you will see the error.

According to the javadocs for thsi deprecated API, the year - the year minus 1900

http://docs.oracle.com/javase/6/docs/api/java/util/Date.html#Date(int, int, int, int, int)

Upvotes: 2

Bohemian
Bohemian

Reputation: 425168

Oddly, months are zero based, so your 10 in the constructor is actually month 11!

And it doesn't stop there: year is from 1900!

From the javadoc:

year - the year minus 1900.

month - the month between 0-11.

Upvotes: 2

Rahul
Rahul

Reputation: 45070

Just add this line

System.out.println("date is 1-10-2013, " + new Date(diff1) + " have passed.");

And you can see that the date is Sat Nov 01 11:06:00 IST 3913.

Date date1 = new Date(2013, 10, 1, 11, 6); is not what you thought it was. That's why you shouldn't use deprecated methods(constructor here).

As @JonSkeet mentioned, Joda is highly recommended over Java's Date.

Upvotes: 2

Abubakkar
Abubakkar

Reputation: 15664

For the second date object, the first argument takes (the year minus 1900).

So in your case if you want 2013, you should pass 113

From java docs Date class

public Date(int year,int month,int date,int hrs,int min)

Parameters:
year - the year minus 1900.
month - the month between 0-11.
date - the day of the month between 1-31.
hrs - the hours between 0-23.
min - the minutes between 0-59.

Upvotes: 0

Optional
Optional

Reputation: 4507

Date.getTime() returns you date and time in milliseconds.

Javadoc says

 Returns the number of milliseconds since January 1, 1970, 00:00:00 GMT
 represented by this Date object.

 @return  the number of milliseconds since January 1, 1970, 00:00:00 GMT
 represented by this date.

In second date, you are missing milliseconds as well

Upvotes: 0

Jon Skeet
Jon Skeet

Reputation: 1501926

This line:

Date date1 = new Date(2013, 10, 1, 11, 6);

... doesn't do what you thing it does. That creates a Date object representing November 1st in the year 3913, at 11:06 local time. I don't think that's what you wanted.

Indeed, if you change your code to include the date itself rather than hard-coding what you think the right value will be, you'll see that:

System.out.println("date is " + date + ", " + diff + " have passed.");
System.out.println("date is " + date1 + ", " + diff1 + " have passed.");

There's a reason that constructor is deprecated - you should pay attention to deprecation, as well as to the documentation.

Now you could just use java.util.Calendar instead - but I'd actually recommend that you use Joda Time instead, if you possibly can. It's a much, much cleaner API than java.util.Calendar/Date. Alternative, if you can use a pre-release of Java 8, that has the new JSR-320 date/time API.

Upvotes: 13

Related Questions