1

I'm looking to create a datetime stamp, then add 10 hours to it, then have a thread check to see if the time has elapsed.

I read through, Time comparison but it seems a bit complicated/convoluted for something so simple. Especially if your time comparison goes across midnight.

My understanding is that java's underlying datetime, is suppose to be a long, if this is true, is there a simple way to add another long to it, such as the number equivalent of 10 hours? Or some other means such as adding two dates?

Note: The solution needs to be part of core java, can't be part of a 3rd party lib.

Community
  • 1
  • 1
James Oravec
  • 19,579
  • 27
  • 94
  • 160
  • 1
    isn't better to schedule the thread to run at the given time, instead of having it polling for the time condition to become true? (ScheduledExecutorService in java.util.concurrent) – guido May 28 '14 at 15:00
  • @guido I like the suggestion. I was actually planning on doing the polling then a sleep for the difference in time, which seems to be the same thing just yours seems more appropriate. I planned to do this as the code will eventually be running on an android device, so I'm not guaranteed the program will always be running, so this simple could happen on launch or resume. I'll look into your suggestion more as I think I can do the same thing on resume/launch with yours. Thx. – James Oravec May 28 '14 at 15:38

4 Answers4

3

You can use a Calendar to perform that math,

Calendar cal = Calendar.getInstance();
cal.add(Calendar.HOUR, 10); // Add 10 hours.
Date date2 = cal.getTime(); // Now plus 10 hours.
Date date = new Date(); // Now.
Elliott Frisch
  • 198,278
  • 20
  • 158
  • 249
  • 1
    What happens if this spans a Daylight Savings Time change? How does Calendar handle that? – Aaron Digulla May 28 '14 at 15:07
  • @AaronDigulla Correctly! As long as the time zone data is correct. Oracle updated when there was that change to the law. – Elliott Frisch May 28 '14 at 15:08
  • 1
    What would be correct in this case? If DST starts, then one hour of the day vanishes (we skip the hour between 2:00 and 3:00). So if `date` is midnight, is `date2` then 11:00, 10:00 or 9:00? And how many actual seconds are between `date` and `date2`? My guess is that OP needs 11:00 in `date2` but it actually contains 10:00. – Aaron Digulla May 28 '14 at 15:13
2

You can use the Date.getTime() method to obtain the underlying timestamp, the timestamp is basically the number of milliseconds elapsed since a defined base instant (1970-01-01 00:00:00 IIRC).

System.currentTimeMillis() allows you the get the "now" instant directly, without any detours using Date, Calendar and the like.

The timestamp can then be manipulated basic math:

 timestamp += TimeUnit.MILLISECONDS.convert(10, TimeUnit.HOURS);

Example of adding 10 hours:

long nowInMilliSince1970 = System.currentTimeMillis();
long tenHoursAsMilli = TimeUnit.MILLISECONDS.convert(10L, TimeUnit.MINUTES);
long tenHoursLater = nowInMilliSince1970 + tenHoursAsMilli;
System.out.println("now in milliseconds: \t\t" + nowInMilliSince1970);
System.out.println("10 hours in milliseconds: \t" + tenHoursAsMilli);
System.out.println("10 hours from now: \t\t" + tenHoursLater);

Checking if the timestamp is in the past is as easy as:

 if (timestamp < System.currentTimeMillis()) {
     System.out.println("timestamp is in the past");
 }

Do note that direct timestamp math has no concept of daylight saving and time zones. If you want that, use a Calendar for math - Calendar implements the dirty exceptional rules for that.

James Oravec
  • 19,579
  • 27
  • 94
  • 160
Durandal
  • 19,919
  • 4
  • 36
  • 70
  • 1
    +1 I actually prefer this solution since it's not prone to errors due to time zones, Daylight Savings Time and other insane ... features ... of the calendar. – Aaron Digulla May 28 '14 at 15:08
  • Thanks Aaron. I accepted the other answer based on its simplicity but watched your additional concerns come after I accepted the answer. I think both are good, but think this is better as you state. – James Oravec May 28 '14 at 15:17
1

Another way of achieving it using just JDK built in stuff is:

long tenHoursFromNow = System.currentTimeMillis() + TimeUnit.HOURS.toMillis(10);

and then in your Thread you would check:

if(System.currentTimeMillis() > tenHoursFromNow)
{
        //Do something as the time has elapsed 
}

Although I would argue that the use of Calendar and Date is clearer as to what the intention of your code is trying to achieve.

Rob Lockwood-Blake
  • 4,688
  • 24
  • 22
0

The bundled java.util.Date and .Calendar are notoriously troublesome. They really should be avoided.

You stated a requirement of no added libraries. So see the java.time part of my answer, using the new package newly added to Java 8. But I urge you to reconsider your reluctance to add a library, especially if you cannot move to Java 8 yet; j.u.Date/Calendar really are that bad.

Both libraries handle anomalies such as Daylight Saving Time.

Consider specifying a time zone rather than rely on the JVM's default. Generally best to work in UTC, and then translate to a local time zone for presentation to the user.

java.time

The java.time package is newly added to Java 8. Inspired by Joda-Time but re-architected. Defined by JSR 310. Extended by the threeten-extra project.

ZonedDateTime tenHoursLater = ZonedDateTime.now().plusHours( 10 );

Joda-Time

Using the Joda-Time 2.3 library.

DateTime tenHoursLater = DateTime.now().plusHours( 10 );

For more info on this kind of use of Joda-Time, see my answer to a similar question.

Community
  • 1
  • 1
Basil Bourque
  • 303,325
  • 100
  • 852
  • 1,154