views:

188

answers:

4

Hi!

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!

A: 

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.

pie154
Post an example which answers his question then? Telling that JodaTime is better is easy since that's a known fact, but is worthless if you don't **actually answer** the question. Post it as a comment then.
BalusC
A: 

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.

Snehal
Snehal, the problem is that you're using the start/end times with the date part in which they were saved (e.g. 12-12-2001). So, you may be comparing today's date (from `userCurrentDate`) to 12-12-2001 (from `companyWorkStart/EndHour`).
Bruno Rothgiesser
But wouldn't it return false, in case that does happen?
Snehal
Yes. But the date part should not be taken into account in the comparison in this case. He's interested in checking if the user's current time is between the start and end working hours so only the time part of the saved companyWorkStart/EndHour dates matter.
Bruno Rothgiesser
Valid point. Thanks!
Snehal
Hi!I inserted your code but! I got the followings in my dates:endTime.getTime() = 25 May 2010 23:00:00startTime.getTime() = 26 May 2010 05:00:00userCurrentTime.getTime() = 26 May 2010 14:25 (this is my time)it doesn't work:) the end time is incorrect!
Riki
+2  A: 

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.

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);
Jesper
Thanks! your code helped me a lot.Another related question:I need to display to the user the company hours in the user's time zone.How can I do it if the companyWorkStartHour and the companyWorkEndHour are integers?
Riki
@Riki: I guess those hours are already in the user's timezone, are they not? You can create a `Calendar` and set the timezone on it like in my code above, and you can set individual fields on the `Calendar` with `set()`, for example: `cal.set(Calendar.HOUR_OF_DAY, companyWorkStartHour);`.
Jesper
Yes- You are right! till you answered me I did just as your suggestion!
Riki
A: 

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) {
  ...
}
Eugene Kuleshov