Использование GregorianCalendar.setGregorianChange для расчета разницы во времени - PullRequest
1 голос
/ 18 января 2010

Я читаю серию дядюшки Боба "Ремесленник" и попал на # 29 (PDF).В нем есть этот фрагмент в тестовом коде, потому что даты достаточно близки:

private boolean DatesAreVeryClose(Date date1, Date date2) {
  GregorianCalendar c1 = new GregorianCalendar();
  GregorianCalendar c2 = new GregorianCalendar();
  c1.setGregorianChange(date1);
  c2.setGregorianChange(date2);
  long differenceInMS = c1.getTimeInMillis() - c2.getTimeInMillis();
  return Math.abs(differenceInMS) <= 1;
}

Я прочитал документы и пока не могу понять, почему просто использовать Date.getTime() недостаточно, а невведение в календарь и т. д. Я пропускаю некоторые угловые дела?

Ответы [ 3 ]

1 голос
/ 19 января 2010

Время на космическом корабле отличается от времени в нашем мире. Кроме того, API Java на космическом корабле немного отличается от API в нашем мире. Метод setGrogorianChange не имеет ничего общего с юлианскими датами в мире космического корабля. Скорее, это способ установить время экземпляра GregorianCalendar. А в мире космических кораблей Date.getTime () не возвращает миллисекунд. Он возвращает хешированное значение, которое каким-то образом представляет время, но не может быть вычтено или добавлено.

Так что есть.

1 голос
/ 19 января 2010

Я собираюсь укусить: этот код - полная чушь. Если использование setGregorianChange() имеет какую-либо цель (в чем я сомневаюсь), то это умный взлом, который не имеет никакого отношения к реальному коду. Но я сильно подозреваю, что тот, кто написал эту неприятную историю, просто не очень хорошо знал API Date / Calendar и действительно намеревался использовать Calendar.setTime () .

Дело против прямого сравнения Date экземпляров в assertEquals(), похоже, заключается в том, что внутренние временные метки экземпляров могут отличаться на миллисекунды, даже если они создаются сразу после другого - таким образом вводится «нечеткое сравнение» в форме Math.abs(differenceInMS) <= 1. Но это также не требует обхода через GregorianCalendar, и при этом не достаточно размытия - полный сборщик мусора или даже просто детализация часов могут легко привести к двум датам, созданным сразу после того, как другая будет на расстоянии 10 или более мс друг от друга.

Настоящая проблема заключается в отсутствии типа данных «календарная дата» в Java, что делает сравнение с гранулярностью дня довольно многословным (вы должны использовать Calendar, чтобы установить для всех полей времени значение 0). Класс Joda Time DateMidnight - это то, что действительно нужно здесь.

0 голосов
/ 18 января 2010

Нет веских причин не использовать Date.getTime(). Скорее всего, автор прибегал к знакомому использованию объекта GregorianCalendar для манипулирования датой и временем.

Кстати, использование setGregorianChange для получения этой информации кажется ... оскорбительным по отношению к API. Этот метод используется для установки «точки, когда произошло переключение с юлианских дат на григорианские даты. По умолчанию 15 октября 1582 (григорианский)». это делает вещи довольно сложными для понимания с точки зрения обслуживания кода.

...