Боретесь с тем, как сравнивать часы с разными часовыми поясами в Java? - PullRequest
7 голосов
/ 26 мая 2010

У меня есть 2 объекта даты в базе данных, которые представляют рабочее время компании.

Мне нужны только часы, но мне нужно сохранить дату. это выглядит так:

Date companyWorkStartHour; 
Date companyWorkEndHour;

часы работы: 12-12-2001-13: 00: 00 финишные часы: 12-12-2001-18: 00: 00

У меня есть часовой пояс компании и пользователя. (мой сервер может быть в другом часовом поясе).

TimeZone userTimeZone;
TimeZone companyTimeZone;

Мне нужно проверить, соответствует ли текущее время пользователя (учитывая его часовой пояс) рабочим часам компании (учитывая часовой пояс компании).

Как я могу это сделать? Я больше недели борюсь с Java-календарем, но безуспешно!

Ответы [ 4 ]

6 голосов
/ 26 мая 2010

Класс java.util.Date - это контейнер, который содержит количество миллисекунд с 1 января 1970 года, 00:00:00 UTC. Обратите внимание, что класс Date ничего не знает о часовых поясах. Используйте класс Calendar, если вам нужно работать с часовыми поясами. ( edit 19-Jan-2017: если вы используете Java 8, используйте новый API даты и времени в пакете java.time).

Класс Date не очень подходит для хранения номера часа (например, 13:00 или 18:00) без даты. Он просто не предназначен для этой цели, поэтому, если вы попытаетесь использовать его таким образом, как вам кажется, вы столкнетесь с рядом проблем, и ваше решение не будет элегантным.

Если вы забудете использовать класс Date для хранения рабочего времени и просто используете целые числа, это будет намного проще:

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);

Если вы также хотите принять во внимание минуты (а не только часы), вы можете сделать что-то вроде этого:

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);
2 голосов
/ 26 мая 2010

Попробуйте что-то вроде этого:

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) {
  ...
}
0 голосов
/ 26 мая 2010

Я не пробовал библиотеку Joda.Этот код должен работать.

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;
}

РЕДАКТИРОВАТЬ Обновлен код для отражения комментариев Бруно.Не следует брать даты времени работы компании.

0 голосов
/ 26 мая 2010

Эй, я не уверен, как бы вы сделали это, используя календарь Java, но я очень рекомендую использовать пакет Joda Time.Это гораздо более простая в использовании система, и она дает вам прямые методы для извлечения всех подкомпонентов данных и времени и даже просто для создания простых объектов времени без даты.Тогда я представляю, что это будет вопрос сравнения двух разностей часовых поясов и вычитания разницы из объекта JodaTime.

...