如何将LDAP时间戳转换为Unix时间戳

时间:2011-01-10 13:10:04

标签: php ldap timestamp

当我使用PHP检索Active Directory的LDAP属性“pwdLastSet”时,我得到一个类似1.29265206716E + 17的值。我知道这个值代表日期“2010年8月17日星期二14:11:11 GMT + 0200”。

如何将此值转换为PHP中的Unix时间戳?谢谢你的任何提示!

9 个答案:

答案 0 :(得分:20)

请参阅here

实际上归结为将FILETIME时间戳转换为UNIX时间戳:

$fileTime = "130435290000000000";
$winSecs       = (int)($fileTime / 10000000); // divide by 10 000 000 to get seconds
$unixTimestamp = ($winSecs - 11644473600); // 1.1.1600 -> 1.1.1970 difference in seconds
echo date(DateTime::RFC822, $unixTimestamp);

答案 1 :(得分:2)

不要问同样的问题来换另一种语言。

Python 3:

from datetime import datetime, timedelta

def ldap2datetime(ts: float):
    return datetime(1601, 1, 1) + timedelta(seconds=ts/10000000)

print(ldap2datetime(132255350424395239).isoformat())
# 2020-02-07T07:44:02.439524

答案 2 :(得分:1)

this page表示它是“自1.1.1601 00:00:00以来通过的100纳秒单位”,这可能会有所帮助。

编辑:1600»»1601

答案 3 :(得分:1)

$dateLargeInt= "1.29265206716E+17"; // nano seconds since jan 1st 1601
$secsAfterADEpoch = $dateLargeInt / (10000000); // seconds since jan 1st 1601
$ADToUnixConvertor=((1970-1601) * 365.242190) * 86400; // unix epoch - AD epoch * number of tropical days * seconds in a day
$unixTsLastLogon=intval($secsAfterADEpoch-$ADToUnixConvertor); // unix Timestamp version of AD timestamp
$lastlogon=date("d-m-Y", $unixTsLastLogon); // formatted date

有关详细信息,请参阅http://php.net/manual/en/ref.ldap.php

答案 4 :(得分:1)

@etranger - 更正:应该是1601而不是1600的时间戳。 请参阅官方微软网站:http://msdn.microsoft.com/en-us/library/ms675243%28v=vs.85%29.aspx

答案 5 :(得分:0)

重击

如果字符串包含 18 位或更多位,则此数字将转换为 +%D_%T 格式的日期。如果超过 18 位,则转换将不正确。如果字符串不包含 18 位或更多位,则以原始形式显示。

$ echo 'something before 132539220002262206 something later' | sed -r 's/(.*)([0-9]{18})(.*$)/echo "\1""$(date +%D_%T -d \@$(((\2\/10000000)-11644473600)))""\3"/e'

$ ldapsearch=(
'dn: CN=John Doe,OU=Neverland,OU=Non-existent,DC=example,DC=com'
'whenCreated: 20210101000000.0Z'
'lastLogon: 132539220002262206'
'pwdLastSet: 132539220003262206'
'sAMAccountName: j.doe'
'userPrincipalName: j.doe@example.com')

$ printf "%s\n" "${ldapsearch[@]}" 
dn: CN=John Doe,OU=Neverland,OU=Non-existent,DC=example,DC=com
whenCreated: 20210101000000.0Z
lastLogon: 132539220002262206
pwdLastSet: 132539220003262206
sAMAccountName: j.doe
userPrincipalName: j.doe@example.com

$ printf "%s\n" "${ldapsearch[@]}" | sed -r 's/(.*)([0-9]{18})(.*$)/echo "\1""$(date +%D_%T -d \@$(((\2\/10000000)-11644473600)))""\3"/e' 
dn: CN=John Doe,OU=Neverland,OU=Non-existent,DC=example,DC=com
whenCreated: 20210101000000.0Z
lastLogon: 01/01/21_00:00:00
pwdLastSet: 01/01/21_00:00:00
sAMAccountName: j.doe
userPrincipalName: j.doe@example.com

答案 6 :(得分:0)

LDAP 中当前时区为 0。如果要增加或减少时区,则需要按照公式 60 秒乘以 60 分钟乘以 X 小时 (60 * 60 * X) = Y 将得到秒。 X 是您要增加或减少的时区。如果要增加时区,请使用 ($ ADToUnixConverter += Y) 否则使用 ($ ADToUnixConverter -= Y)。

$time = '132608472643065510'; //nano seconds since jan 1st 1601
$secsAfterADEpoch = $ldapTime / 10000000; //seconds since jan 1st 1601
$ADToUnixConverter = ((1970 - 1601) * 365 - 3 + round((1970 - 1601) / 4)) * 86400; //unix epoch - AD epoch * number of tropical days * seconds in a day
$ADToUnixConverter += 25200; // (+7 hours) 
$lastLogonTimesamp= ($secsAfterADEpoch - $ADToUnixConverter);
echo date("Y/m/d H:i:s", $lastLogonTimesamp)

答案 7 :(得分:0)

Node.JS/浏览器 JS:

const convertInt64Timestamp = timestamp => {
   const offsetInMs = Number.parseInt(timestamp) / 10_000;
   const baseDate = Date.parse('1601-01-01T00:00:00Z');
   return new Date(baseDate + offsetInMs);
};

答案 8 :(得分:-2)

我认为第一步是了解LDAP值的真正含义 - 一旦完成,其余部分就很容易了。

处理日期的LDAP属性很少。 pwdLastSet accountExpires 的值为 127524839567199000 whenChanged 的值为 20050210223453.0Z - 两个值都指的是同一个日期 10-FEB-2005

有关简单说明,请参阅http://maxvit.net/convert_ldap_dates

希望这有帮助!