Riki
Riki

Reputation: 145

Struggling with how to compare hours with different time zones in Java?

I have 2 date object in the database that represent the company's working hours.

I only need the hours but since I have to save date. it appears like this:

Date companyWorkStartHour; 
Date companyWorkEndHour;

start hours: 12-12-2001-13:00:00 finish hours: 12-12-2001-18:00:00

I have the timezone of the company and of the user. (my server may be in another timezone).

TimeZone userTimeZone;
TimeZone companyTimeZone;

I need to check if the user's current time (considering his timezone) is within the company working hours (considering the company's time zone).

How can I do it? I am struggling for over a week with Java calendar and with no success!

Upvotes: 8

Views: 13576

Answers (4)

Jesper
Jesper

Reputation: 206776

The java.util.Date class is a container that holds a number of milliseconds since 1 January 1970, 00:00:00 UTC. Note that class Date doesn't know anyting about timezones. Use class Calendar if you need to work with timezones. (edit 19-Jan-2017: if you are using Java 8, use the new date and time API in package java.time).

Class Date is not really suited for holding an hour number (for example 13:00 or 18:00) without a date. It's simply not made for that purpose, so if you try to use it like that, as you seem to be doing, you'll run into a number of problems and your solution won't be elegant.

If you forget about using class Date to store the working hours and just use integers, this will be much simpler:

Date userDate = ...;
TimeZone userTimeZone = ...;

int companyWorkStartHour = 13;
int companyWorkEndHour = 18;

Calendar cal = Calendar.getInstance();
cal.setTime(userDate);
cal.setTimeZone(userTimeZone);

int hour = cal.get(Calendar.HOUR_OF_DAY);
boolean withinCompanyHours = (hour >= companyWorkStartHour && hour < companyWorkEndHour);

If you also want to take minutes (not just hours) into account, you could do something like this:

int companyWorkStart = 1300;
int companyWorkEnd = 1830;

int time = cal.get(Calendar.HOUR_OF_DAY) * 100 + cal.get(Calendar.MINUTE);
boolean withinCompanyHours = (time >= companyWorkStart && time < companyWorkEnd);

Upvotes: 6

pie154
pie154

Reputation: 613

Hey I am not sure how you would do this using the Java calendar but I would highly recommend using the Joda Time package. It's a much simpler system to use and it gives you direct methods to extracts all subcomponents of data and time and even just to create simple time objects without the date involved. Then I imagine it would be a matter of comparing the 2 timezone differences and subtracting the difference from the JodaTime object.

Upvotes: 0

Eugene Kuleshov
Eugene Kuleshov

Reputation: 31795

Try something like this:

Calendar companyWorkStart = new GregorianCalendar(companyTimeZone);
companyWorkStart.setTime(companyWorkStartHour);

Calendar companyWorkEnd = new GregorianCalendar(companyTimeZone);
companyWorkEnd.setTime(companyWorkEndHour);

Calendar user = new GregorianCalendar(userTimeZone);
user.setTime(userTime);

if(user.compareTo(companyWorkStart)>=0 && user.compareTo(companyWorkEnd)<=0) {
  ...
}

Upvotes: 2

Snehal
Snehal

Reputation: 7486

I haven't tried the Joda library. This code should work.

public boolean checkUserTimeZoneOverLaps(TimeZone companyTimeZone,
        TimeZone userTimeZone, Date companyWorkStartHour,
        Date companyWorkEndHour, Date userCurrentDate) {

    Calendar userCurrentTime = Calendar.getInstance(userTimeZone);
    userCurrentTime.setTime(userCurrentDate);
    int year = userCurrentTime.get(Calendar.YEAR);
    int month = userCurrentTime.get(Calendar.MONTH);
    int day = userCurrentTime.get(Calendar.DAY_OF_MONTH);

    Calendar startTime = Calendar.getInstance(companyTimeZone);
    startTime.setTime(companyWorkStartHour);
    startTime.set(Calendar.YEAR, year);
    startTime.set(Calendar.MONTH, month);
    startTime.set(Calendar.DAY_OF_MONTH, day);

    Calendar endTime = Calendar.getInstance(companyTimeZone);
    endTime.setTime(companyWorkEndHour);
    endTime.set(Calendar.YEAR, year);
    endTime.set(Calendar.MONTH, month);
    endTime.set(Calendar.DAY_OF_MONTH, day);

    if (userCurrentTime.after(startTime) && userCurrentTime.before(endTime)) {
        return true;
    }
    return false;
}

EDIT Updated the code to reflect Bruno's comments. Shouldn't be taking the dates of the company work timings.

Upvotes: 0

Related Questions