当我使用PHP检索Active Directory的LDAP属性“pwdLastSet”时,我得到一个类似1.29265206716E + 17的值。我知道这个值代表日期“2010年8月17日星期二14:11:11 GMT + 0200”。
如何将此值转换为PHP中的Unix时间戳?谢谢你的任何提示!
答案 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
希望这有帮助!