2013-10-15 53 views
0

在處理從我通過LDAP訪問的活動目錄返回的結果時,我一直試圖瞭解日期和時間計算的不同結果。我在某處讀到夏季時間可能會導致一些差異?我不明白爲什麼使用1601年1月1日的日曆來糾正時間與4小時的差異,或者爲什麼在Java中添加日期出現1小時的差異。我假設答案是,在嘗試轉換它們之前,我應該對原始值進行所有算術運算,但這並不能解釋爲什麼使用日曆校正時間有四小時差異。Java LDAP日期計算

這裏是我的例子:

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

我懷疑問題與默認時區。例如,如果您的JVM在​​中,那麼將不是日期午夜,而是1600-12-31T23:00:00.000Z,而不是win32Epoch。總是閱讀JavaDoc,並在有意義的地方使用基於時區的構造函數。

您還在非UTC時區打印日期(EDT & EST)。這可能會使計算及其結果更加不清楚。


對於日期時間計算,我只能推薦Joda Time。這個框架作爲新的Date and Time API的基礎,將會出現在Java 8中。

+1

如果我在UTC時區得到日曆實例,請將日期設置爲1月1日1601 00:00:00日期,毫秒工作與「靜態」校正器相同。然後我的數學成真了。謝謝您的幫助。 –

+1

我查看了喬達時間,並正在使用它進行一些計算。在Java中找到兩個日期之間的日子非常困難。喬達時間更容易。感謝您的建議。 –