比较两个Java日历时,如何规范化时区?

时间:2012-11-27 21:36:54

标签: java calendar

我对11月7日感到愤怒。

我已经编写了一种方法来计算两个Java Date对象之间的天数(在它被提及之前,JodaTime不是一个选项) - 该方法在大多数情况下工作,但是当开始xor结束日期时在夏令时期间,输出会在一天内消失。

日历是否有某种方法可以覆盖日期的时区?我不关心日期实际上是什么时区,但它们必须是同一个!

以下代码:

public int getDayRange() {

        //startDate = "Sat Nov 06 00:00:00 EDT 2010";
        //endDate = "Sun Nov 07 23:59:59 EST 2010";

    TimeZone tz = TimeZone.getTimeZone("UTC");

    GregorianCalendar cal1 = new GregorianCalendar(tz); 
    GregorianCalendar cal2 = new GregorianCalendar(tz); 

    cal1.setTime(startDate);
    cal2.setTime(endDate);

    long ms1 = cal1.getTime().getTime(); 
    long ms2 = cal2.getTime().getTime(); 
    long difMs = ms2-ms1; 
    long msPerDay = 1000*60*60*24; 

    double days = difMs / msPerDay;

    return (int) Math.floor(days)+1;
        //returns 3(!!!) days (wrong)
}

2 个答案:

答案 0 :(得分:5)

永远不要尝试使用1000 * 60 * 60 * 24作为一天。这是完全错的。如果您确实需要由于某些原因自己实施计算,请使用日历上的YEAR和DAY_OF_YEAR字段来计算实际天数的差异。

您不能简单地“覆盖”java.util.Date的时区,因为它没有与之关联的时区信息。您需要知道要解释的时区,并在将其转换为人工表示时使用该时区。正如您所发现的,任意使用UTC来解释它将无法提供一致的结果!

  public int getDayRange() {

        //startDate = "Sat Nov 06 00:00:00 EDT 2010";
        //endDate = "Sun Nov 07 23:59:59 EST 2010";

    TimeZone tz1 = TimeZone.getTimeZone("EDT");
    TimeZone tz2 = TimeZone.getTimeZone("EST");

    GregorianCalendar cal1 = new GregorianCalendar(tz1); 
    GregorianCalendar cal2 = new GregorianCalendar(tz2); 

    cal1.setTime(startDate);
    cal2.setTime(endDate);

    if (cal1.get(Calendar.YEAR) == cal2.get(Calendar.YEAR)) {
        return cal2.get(Calendar.DAY_OF_YEAR) - cal1.get(Calendar.DAY_OF_YEAR) + 1;
    } else {
        //this gets complicated, but you can see what to do, plenty of examples online
    }

  }

答案 1 :(得分:1)

您的系统应以UTC格式存储所有时间戳! 如果不是,你永远不会那样工作!
然后差异计算很简单。

如果您还需要显示localTime,则必须将TimeZone与日期作为一对存储:示例:(long timeUtc,int timezoneOffSetToUtc)。 timezoneOffSetToUtc是在对的创建日期有效的偏移量。

TimeZone只能从String中实例化(“奥地利/维也纳”)。