在处理从我通过LDAP访问的活动目录返回的结果时,我一直在尝试了解日期和时间计算的不同结果。我在某处看到,夏令时间可能导致一些差异?我无法理解为什么使用1601年1月1日日历来纠正时间会产生4小时的差异,或者为什么在Java中添加天数会产生一小时的差异。我假设答案是我应该在尝试转换它们之前对原始值进行所有算术运算,但这不能解释为什么用日历校正时间有四个小时的差异。
以下是我的例子:
import java.util.Calendar;
import java.util.Date;
import java.util.GregorianCalendar;
import org.apache.commons.lang3.time.DateUtils;
public class Test {
public static void main(String[] args) {
Long millisecondCorrector = 10000L;
Long epochCorrector = 11644473600000L;
GregorianCalendar win32Epoch = new GregorianCalendar(1601, Calendar.JANUARY, 1, 0, 0, 0);
Long maxPwdAge = -78624000000000L;
Long pwdLastSet = 130256481664603612L;
System.out.println("Max Password Age in milliseconds : " + (Math.abs(maxPwdAge) / millisecondCorrector));
System.out.println("Max Password Age in days : " + (Math.abs(maxPwdAge) / millisecondCorrector / DateUtils.MILLIS_PER_DAY));
System.out.println("***********************************************************************************************************");
System.out.println("Password Last Set (Static corrector) : " + new Date(pwdLastSet / millisecondCorrector - epochCorrector));
System.out.println("Password Last Set (Calendar corrector) : " + new Date(pwdLastSet / millisecondCorrector + win32Epoch.getTimeInMillis()));
System.out.println("***********************************************************************************************************");
System.out.println("Password Expiration (Static corrector) : " + new Date((pwdLastSet + Math.abs(maxPwdAge)) / millisecondCorrector - epochCorrector));
System.out.println("Password Expiration (Day arithmetic w/ static corrector) : " + DateUtils.addDays(new Date(pwdLastSet / millisecondCorrector - epochCorrector), (int) (Math.abs(maxPwdAge) / millisecondCorrector / DateUtils.MILLIS_PER_DAY)));
System.out.println("Password Expiration (Calendar corrector) : " + new Date((pwdLastSet + Math.abs(maxPwdAge)) / millisecondCorrector + win32Epoch.getTimeInMillis()));
System.out.println("Password Expiration (Day arithmetic w/ calendar corrector) : " + DateUtils.addDays(new Date(pwdLastSet / millisecondCorrector + win32Epoch.getTimeInMillis()), (int) (Math.abs(maxPwdAge) / millisecondCorrector / DateUtils.MILLIS_PER_DAY)));
}
}
以下是结果:
Max Password Age in milliseconds : 7862400000
Max Password Age in days : 91
***********************************************************************************************************
Password Last Set (Static corrector) : Mon Oct 07 15:36:06 EDT 2013
Password Last Set (Calendar corrector) : Mon Oct 07 20:36:06 EDT 2013
***********************************************************************************************************
Password Expiration (Static corrector) : Mon Jan 06 14:36:06 EST 2014
Password Expiration (Day arithmetic w/ static corrector) : Mon Jan 06 15:36:06 EST 2014
Password Expiration (Calendar corrector) : Mon Jan 06 19:36:06 EST 2014
Password Expiration (Day arithmetic w/ calendar corrector) : Mon Jan 06 20:36:06 EST 2014
作为后续行动,我想我应该问是否有任何好的库来处理这类计算?似乎这段代码已被编写了很多次!
答案 0 :(得分:0)
我怀疑是否存在默认时区问题。例如,如果您的JVM位于GMT+1
,则win32Epoch
不会是午夜,而是1600-12-31T23:00:00.000Z
。始终阅读JavaDoc并使用基于时区的构造函数。
您还在非UTC时区(EDT& EST)打印日期。这可能会使计算及其结果更加不清楚。
对于日期时间计算,我只能推荐Joda Time。该框架作为新Date and Time API的基础,将出现在Java 8中。