0

Take a look at the following commands:

$ sudo ln -fs /usr/share/zoneinfo/US/Pacific localtime
$ date
Mon Oct 13 15:29:02 PDT 2014
$ sudo ln -fs /usr/share/zoneinfo/US/Hawaii localtime
$ date
Mon Oct 13 12:29:20 HST 2014

That is all well and good. Now I have some software written in java that needs to know how many minutes until midnight so it can perform some maintenance.

Here is the code I came up with:

// Time to perform maintenance
String rawTime = "23:59";
int hours = Integer.parseInt(rawTime.substring(0, 2));
int minutes = Integer.parseInt(rawTime.substring(3, 5));

// Get current Time
Calendar c = Calendar.getInstance();
long now = c.getTimeInMillis();
Date dateNow = new Date(now);
System.out.println(new Date(now));

// Get midnight
c.set(Calendar.HOUR_OF_DAY, hours);
c.set(Calendar.MINUTE, minutes);
c.set(Calendar.SECOND, 0);
c.set(Calendar.MILLISECOND, 0);
Date midnight = new Date(c.getTimeInMillis());

// Get Difference
System.out.println(String.format("Calc minutes from %s to %s", dateNow, midnight));       
long result = ((midnight.getTime()/60000) - (dateNow.getTime()/60000));
System.out.println((int) result);

Output when linux is set to Hawaii time zone:

Calc minutes from Mon Oct 13 15:36:51 PDT 2014 to Mon Oct 13 23:59:00 PDT 2014
Result:  503

As you can see, I'm not getting the correct time... I'm getting PDT instead of HST. I'm not that concerned with why toString() of a date returns PDT since it is time zone independent but I am concerned with how I should calculate this?

Let's just start with '11:59' calculate how many minutes until '11:59' for whatever linux thinks the time is...I am open to a solution where I set the linux time in a different fashion.

Thanks! this should be this hard...

aelstonjones
  • 382
  • 2
  • 8
  • 25
  • I see the problem. I wonder if it might be better to use UTC instead of time zones? – Alvin Bunk Oct 13 '14 at 22:57
  • Try calling `c.getTime()` after setting the date parts. IIRC it does some internal recalc that makes the sets take effect. It's basically a broken class. Consider using JodaTime – Bohemian Oct 13 '14 at 23:01
  • 1
    Java is not seeing your change in the OS. Maybe you're on a distro that needs you to set /etc/timezone? Maybe your code is running inside an application container that has -Duser.timezone set somewhere? – Affe Oct 13 '14 at 23:04
  • 1
    Are you using Java 8? Now there is [`Duration.between(Temporal,Temporal)`](http://docs.oracle.com/javase/8/docs/api/java/time/Duration.html#between-java.time.temporal.Temporal-java.time.temporal.Temporal-) – Elliott Frisch Oct 13 '14 at 23:09
  • I did set the /etc/timezone. I will look at -Duser.timezone. Also, I will look at JodaTime – aelstonjones Oct 14 '14 at 16:11

1 Answers1

0

The java.util.Date and .Calendar classes are notoriously troublesome. Avoid them. Use either Joda-Time or the new java.time package in Java 8.

In both Joda-Time and java.time, a date-time object truly knows its own assigned time zone (unlike java.util.Date).

Here is some example code in Joda-Time 2.5.

DateTimeZone timeZoneHawaii = DateTimeZone.forID( "Pacific/Honolulu" );
DateTime now = DateTime.now( timeZoneHawaii );
DateTime dayStart = now.plusDays(1).withTimeAtStartOfDay();  // Usually 00:00:00.000 but not always because of Daylight Saving Time or possibly other anomalies.
int minutesUntilDayStartsInHawaii = Minutes.minutesBetween( now, dayStart ).getMinutes();
Basil Bourque
  • 303,325
  • 100
  • 852
  • 1,154
  • The problem is that I do not know the time zone ahead of time. – aelstonjones Oct 14 '14 at 16:10
  • @aelstonjones ?? So what exactly is your question? You want to calculate elapsed time in a time zone you don't know? That makes no sense, like saying you want to convert an amount of money to a currency you don't know. – Basil Bourque Oct 14 '14 at 16:14
  • If the system is set to HST then I would like to get minutes to midnight in that timezone. If I set the system to PST, I would like to use that time zone. I do not want to compile the timezone into the code. I guess I could use a config value but I was hoping java had something built in. The main issue I am having is that it doesn't matter what I set my systems time zone, I always get PST. I am investigating -Duser.timezone because maybe the method I showed isn't correct. – aelstonjones Oct 14 '14 at 16:55
  • That is the correct way and is the answer to what I posted. Thanks for the help. I was able to use http://stackoverflow.com/questions/7026182/how-to-set-java-timezone to help me set the time correct in linux – aelstonjones Oct 14 '14 at 17:16