Clinton
Clinton

Reputation: 23145

Simple date class in Java

Is there a date class in Java which I can construct with a year, month, day, hour, minute, second and millisecond and then do comparisons which give the number of milliseonds between two date values, ignoring things like daylight saving, leap seconds etc? Can I use the Calendar class for this? I was thinking about doing that, but it talks about leap seconds and daylight saving, and I don't want that to affect the calculations.

It is important that the following invariant holds true all the times:

For all y1, y2, m1, m2, d1, d2, h, m, s, ms:

(
    f(y1, m1, d1, h, m, s, ms).getTimeInMillis() - 
    f(y2, m2, d2, h, m, s, ms).getTimeInMillis()
) 
% 
(24 * 60 * 60 * 1000) == 0

I basically need to know what the function f should be.

Upvotes: 0

Views: 2445

Answers (6)

Basil Bourque
Basil Bourque

Reputation: 340098

tl;dr

Use java.time classes in modern Java.

Duration
.between(
    LocalDateTime.of( year, month, dayOfMonth, hour, minute ) ,
    LocalDateTime.of( year, month, dayOfMonth, hour, minute )
)
.toMillis()

Beware: Use of LocalDateTime does not account for real-world anomalies found with time zones. The code above assumes generic 24-hour days. But with time zones, days can be 23 hours long, 25 hours long, or other lengths.

Avoid legacy date-time classes

Avoid using the terribly flawed Calendar class. That class is part of the legacy date-time classes that were supplanted by the modern java.time classes defined in JSR 310.

java.time

Time zone

Your code neglected to specify a time zone. Therefore, Calendar implicitly applied the JVM’s current default time zone.

I suggest not relying upon such an implicit default. Specify your desired/expected time zone explicitly, even if you do want the default.

ZoneId zoneId = ZoneId.of( "Asia/Tokyo" ) ;

Or:

ZoneId zoneId = ZoneId.systemDefault() ;

ZonedDateTime

To represent a moment as seen in a particular time zone, use the ZonedDateTime class with its of method.

ZonedDateTime zdt = ZonedDateTime.of( year, month, dayOfMonth, hour, minute, second, nanoOfSecond, zoneId ) ;

The ZonedDateTime class accounts for the anomalies that come with time zones, such as Daylight Saving Time (DST).

LocalDateTime

But you said specifically you want to ignore time zone anomalies. For that, use the LocalDateTime class. This class ignores time zone rules.

LocalDateTime ldt = LocalDateTime.of( year, month, dayOfMonth, hour, minute ) ;

To calculate elapsed time, use Duration class.

Duration duration = Duration.between( someLdt , otherLdt ) ;

You want to know the elapsed time in milliseconds.

long milliseconds = duration.toMillis() ;

Upvotes: 1

Grzegorz Gajos
Grzegorz Gajos

Reputation: 2363

You can use DateUtils for date manipulation. There is also entire new API since Java 8.

Upvotes: 0

Brian C.
Brian C.

Reputation: 7986

I would try using Joda DateTime where you could do

DateTime d1 = new DateTime(y1,m1,d1,h1,m1,s1,ms1);
DateTime d2 = new DateTime(y2,m2,d2,h2,m2,s2,ms2);
long delta = d1.toMillis() - d2.toMillis();

Also consider:

 DateTime d1 = new DateTime(y1,m1,d1,h1,m1,s1,ms1);
 DateTime d2 = new DateTime(y2,m2,d2,h2,m2,s2,ms2);
 Duration delta = new Duration( d1, d2);
 int days = delta.toPeriod().getDays();

If you have unusual needs you may want to look at Joda Chronology objects.

Upvotes: 0

Oleg Pavliv
Oleg Pavliv

Reputation: 21192

Yes, you can use the Calendar class for your calculations. You can construct your dates and use getTimeInMillis() for comparison.

I would also recommend a joda-time java library which has a lot of functionality for dates. It has a better performance as well.

Upvotes: 3

asgs
asgs

Reputation: 3984

You can use the Calendar class to set your year, month and other stuff.

Look at the calendar.set() and the calendar.getTime() methods' javadocs.

Then, date.getTime() will give you the absolute milliseconds from 1970.

Upvotes: 1

Peter Lawrey
Peter Lawrey

Reputation: 533870

You can just use long. But you still have to worry about leap days. You can do comparisons like.

long start = System.currentTimeMillis(); // nanoTime is better for benchmarks
// do something.
long time = System.currentTimeMillis() - start;

However, if you have to consider leap years etc. Calendar may be the best choice as dates are naturally messy ;) You could consider JodaTime library which is nicer but not much simpler.

Upvotes: 0

Related Questions