1

ldapsearch を実行するときに、NSTask 応答から pwdLastSet 値を解析しようとしています。値 (129875475241190194) の抽出に成功し、それを NSDate オブジェクトに変換しようとしています。

参照: http://www.chrisnowell.com/information_security_tools/date_converter/Windows_active_directory_date_converter.asp

上記のページから Javascript コードを抽出して変換しようとしましたが、別の日付が表示されます。

        int iYearsFrom1601to1970 = 1970 - 1601;
        int iDaysFrom1601to1970 = iYearsFrom1601to1970 * 365;
        iDaysFrom1601to1970 += (int)(iYearsFrom1601to1970 / 4); // leap years
        iDaysFrom1601to1970 -= 3; // non-leap centuries (1700,1800,1900).  2000 is a leap century
        float iSecondsFrom1601to1970 = iDaysFrom1601to1970 * 24 * 60 * 60;

        int iTotalSecondsSince1601 = (int)(129875475241190194 / 10000000);

        float iTotalSecondsSince1970 = iTotalSecondsSince1601 - iSecondsFrom1601to1970;

        NSDate *date = [NSDate dateWithTimeIntervalSince1970:iTotalSecondsSince1970];

どんな助けでも大歓迎です。

ありがとう!

4

3 に答える 3

14

これが私がそれを行う方法です:

NSDateComponents *base = [[NSDateComponents alloc] init];
[base setDay:1];
[base setMonth:1];
[base setYear:1601];
[base setEra:1]; // AD

NSCalendar *gregorian = [[NSCalendar alloc] initWithCalendarIdentifier:NSGregorianCalendar];

NSDate *baseDate = [gregorian dateFromComponents:base];
[base release];
[gregorian release];

NSTimeInterval timestamp = 129875475241190194.0 / 10000000.0;

NSDate *finalDate = [baseDate dateByAddingTimeInterval:timestamp];

これにより、finalDateが得られます2012-07-24 03:58:22 +0000

タイムスタンプは 1601 年 1 月 1 日 00:00 UTC からの時間間隔であるため、-dateByAddingTimeInterval:メソッド onNSDateを使用してタイムスタンプを基準日に追加し、最終的なNSDate.

それが完了したら、それを実行して、NSDateFormatter表示用にフォーマットすることができます。

于 2012-08-15T23:16:09.223 に答える
2

ベースタイム間の大胆な変換が正しいと仮定すると、警告をキャストするのではなく、実際に警告を確認することが実際に役立つ場合があります。

int main(void)
{
    int iTotalSecondsSince1601 = (129875475241190194 / 10000000);
    return 0;
}

stieber@gatekeeper:~$ clang++ Test.cpp
Test.cpp:4:8: warning: implicit conversion from 'long' to 'int' changes value from 12987547524 to 102645636
....

それはかなりの違いを説明するはずです...

于 2012-08-15T23:23:12.983 に答える
0

これを試して

NSTimeInterval value = 129875475241190194;
// instead of trying to compute seconds between 1601 and 1970
const NSTimeInterval EPOCH = 11644473600;
const NSTimeInterval NANO = 10000000;

NSTimeInterval seconds = value / NANO - EPOCH;
NSDate *answer = [NSDate dateWithTimeIntervalSince1970:seconds];

また、これは 1601 年以降の秒数を計算したくない理由です: ...過去千年紀では、1600 年と 2000 年はうるう年でしたが、1700 年、1800 年、1900 年はそうではありませんでした。グレゴリオ暦に関するウィキペディアからの抜粋。

EPOCH の値については、Active Directory の「LastLogon:」時刻を (UNIX) 読み取り可能な時刻に変換 する で説明されています。

注: 12-31-1601 (11644473600) から始まるaccountExpiresに関する情報。ただし、値lastLogonおよびlastLogonTimeStampは、この値 (11676009600) を計算する日付として 01-01-1601 を使用します。

于 2012-08-16T13:19:40.920 に答える