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

t98cgbkg  于 2023-01-08  发布在  PHP
关注(0)|答案(9)|浏览(176)

当我使用PHP检索活动目录的LDAP属性“pwdLastSet”时,我得到了一个类似于1.29265206716E+17的值。我知道这个值表示日期“2010年8月17日星期二14:11:11 GMT+0200”。
如何在PHP中将这个值转换为Unix时间戳?谢谢您的提示!

nr7wwzry

nr7wwzry1#

请看这里。
实际上,它可以归结为将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);
raogr8fs

raogr8fs2#

而不是对另一种语言问同样的问题。

  • 巨蟒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
gupuwyp2

gupuwyp23#

$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

zfciruhq

zfciruhq4#

@陌生人-更正:时间戳应从1601开始,而不是1600。请参阅Microsoft官方网站:http://msdn.microsoft.com/en-us/library/ms675243%28v=vs.85%29.aspx

4xrmg8kj

4xrmg8kj5#

this page表示“自1.1.1601 00:00:00以来已通过100纳秒单位”,这可能会有所帮助。
编辑:1600至1601

siotufzp

siotufzp6#

NodeJS /浏览器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);
};
7tofc5zh

7tofc5zh7#

猛击
如果字符串包含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
pkln4tw6

pkln4tw68#

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)
qq24tv8q

qq24tv8q9#

PHP解决方案

基于这个答案https://stackoverflow.com/a/67992361/1936720,可以在PHP中使用

$time = '133220124000000000';
$date = new DateTime('1601-01-01', new DateTimeZone('UTC'));
$date->modify('+' . ($time / 10000000) . ' seconds');

相关问题