如何在Java中比较不同时区的小时数?

如何在Java中比较不同时区的小时数?,java,date,calendar,timezone,Java,Date,Calendar,Timezone,我在数据库中有两个日期对象,代表公司的工作时间 我只需要时间,但因为我必须保存日期。看起来是这样的: Date companyWorkStartHour; Date companyWorkEndHour; int companyWorkStart = 1300; int companyWorkEnd = 1830; int time = cal.get(Calendar.HOUR_OF_DAY) * 100 + cal.get(Calendar.MINUTE); boolean withi

我在数据库中有两个日期对象,代表公司的工作时间

我只需要时间,但因为我必须保存日期。看起来是这样的:

Date companyWorkStartHour; 
Date 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);
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) {
  ...
}
开始时间:12-12-2001-13:00:00 完成时间:12-12-2001-18:00:00

我有公司和用户的时区。(我的服务器可能在另一个时区)

我需要检查用户的当前时间(考虑到他的时区)是否在公司工作时间内(考虑到公司的时区)


我怎么做?我用Java日历挣扎了一个多星期,但没有成功

嘿,我不确定您将如何使用Java日历来实现这一点,但我强烈建议您使用Joda时间包。这是一个使用起来简单得多的系统,它提供了直接的方法来提取数据和时间的所有子组件,甚至只创建简单的时间对象而不涉及日期。然后我想这将是一个比较两个时区差异并从JodaTime对象中减去差异的问题。

我还没有尝试过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;
}
编辑
更新代码以反映Bruno的评论。不应记录公司工作时间的日期。

java.util.Date类是一个容器,自1970年1月1日00:00:00 UTC起,该容器可容纳毫秒数。请注意,class
Date
对时区一无所知。如果需要使用时区,请使用class
Calendar
。(编辑2017年1月19日:如果您使用的是Java 8,请在package
Java.time
中使用新的日期和时间API)

Class
Date
不适合保存没有日期的小时数(例如13:00或18:00)。它根本不是为这个目的而设计的,所以如果你像你现在这样使用它,你会遇到很多问题,你的解决方案也不会很优雅

如果您忘记了使用class
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);
dateuserdate=。。。;
时区用户时区=。。。;
int companyWorkStartHour=13;
int COMPANYWORKENDHOURE=18;
Calendar cal=Calendar.getInstance();
校准设置时间(用户日期);
校准设置时区(用户时区);
int hour=cal.get(日历小时);
布尔值,不兼容小时数=(小时数>=公司工作开始时间和小时数<公司工作开始时间);
如果您还想考虑几分钟(而不仅仅是几小时),您可以这样做:

Date companyWorkStartHour; 
Date 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);
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) {
  ...
}
int companyWorkStart=1300;
int companyWorkEnd=1830;
int time=cal.get(日历小时)×100+cal.get(日历分钟);
布尔值,不兼容工时=(时间>=公司工作开始时间和时间<公司工作结束时间);

尝试以下方法:

Date companyWorkStartHour; 
Date 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);
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) {
  ...
}
Calendar companyWorkStart=新的GregorianCalendar(companyTimeZone);
companyWorkStart.setTime(companyWorkStartHour);
日历companyWorkEnd=新的GregorianCalendar(companyTimeZone);
companyWorkEnd.设置时间(companyWorkEndHour);
日历用户=新的GregorianCalendar(用户时区);
user.setTime(userTime);

如果(user.compareTo(companyWorkStart)>=0&&user.compareTo(companyWorkEnd)Snehal,问题是您使用的是开始/结束时间与保存它们的日期部分(例如12-12-2001)。因此,您可能会将今天的日期(从
userCurrentDate
)与12-12-2001(从
companyWorkStart/EndHour
)进行比较。但是如果真的发生这种情况,它不会返回false吗?是的。但是在本例的比较中不应考虑日期部分。他感兴趣的是检查用户的当前时间是否在开始和结束工作时间之间,因此只有保存的公司工作开始/结束时间日期的时间部分才重要。嗨!我插入了您的代码,但是!我开始了t我的日期中包含以下内容:endTime.getTime()=2010年5月25日23:00:00 startTime.getTime()=2010年5月26日05:00:00 userCurrentTime.getTime()=2010年5月26日14:25(这是我的时间)无效:)结束时间不正确!贴一个例子来回答他的问题?告诉JodaTime更好是很容易的,因为这是一个已知的事实,但是如果你不真正回答这个问题,那就毫无价值了。那么就把它作为评论发布吧。DB本身的时区已经考虑在内了吗?当您以java.sql.Date的形式从数据库中查询小时数并立即打印时,小时数是否正确?一般建议将所有时间存储在UTC中,并且仅转换为其他时区,以便输入和显示。那么比较应该是直截了当的<代码>日期
及其现代替代品
即时
都在内部使用UTC。谢谢!你的代码帮了我很多。另一个相关问题:我需要向用户显示用户时区中的公司时间。如果companyWorkStartHour和companyWorkEndHour是整数,我该怎么做呢?@Riki:我想这些小时已经在用户的时区了,不是吗?您可以创建一个
日历
并在其上设置时区,就像上面我的代码一样,您可以使用
set()
日历
上设置各个字段,例如:
cal.set(Calendar.HOUR OF_DAY,companyWorkStartHour)。是的-你说得对!直到你回答我,我才按照你的建议去做!我也有类似的情况。但是这个解决方案对我不起作用。因为我的开始时间和结束时间不是固定的13和18;它可以是任何东西。所以,当范围为23和1时,解决方案失败。对这种情况有什么想法吗?