PHP : 如何将 LDAP 中的 Windows FILETIME 字符串转换为可读的 DATE?
PHP : How to convert a Windows FILETIME String from LDAP into a readable DATE?
我正在查询 MS LDAP,一些关于用户的日期字段具有这种值:132497313049180481
。
它似乎是 Windows FILETIME 格式,用于 LDAP 和 Active Directory 中的某些信息作为 timestamp.
如何将其转换成可读的日期?
这将Windows FILETIME(例如:132497313049180481
)转换为人类可读的日期时间(在此案例:“2020-11-13 08:55:04”)。
希望有用:
$filetime = "132497313049180481";
echo filetimeToStr($filetime); // Will display "2020-11-13 08:55:04"
function filetimeToStr($filetime){
date_default_timezone_set ("UTC"); //For a result not depending on server time zone.
$resp = (int)($filetime / 10000000); //Number of seconds since 1601-01-01.
$diff = 11644473600; //Number of seconds between FILETIME & Unix timestamp.
$resp = $resp - $diff; //Actual Unix timestamp matching your filetime.
$resp = date("Y-m-d H:i:s", $resp);
return $resp;
}
想知道 11644473600 来自哪里?
MSDN 说 FILETIME :
Contains a 64-bit value representing the number of 100-nanosecond
intervals since January 1, 1601 (UTC). https://docs.microsoft.com/fr-be/windows/win32/api/minwinbase/ns-minwinbase-filetime?redirectedfrom=MSDN
关于 Unix 时间戳:
Unix epoch is the time 00:00:00 UTC on 1 January 1970 ... every day is
treated as if it contains exactly 86400 seconds.
https://en.wikipedia.org/wiki/Unix_time
date_default_timezone_set ("UTC"); //For a result not depending on server time zone.
$start_date = date_create("1601-01-01");
$end_date = date_create("1970-01-01");
$diff = date_diff($start_date, $end_date);
$diff = (int)$diff->format("%a"); //Number of days between FILETIME & Unix timestamp
$diff = ($diff * 86400); //Number of seconds between FILETIME & Unix timestamp
echo $diff; //Will display 11644473600
已编辑
为不依赖于服务器时区的结果添加了 date_default_timezone_set ("UTC");
(感谢 @jspit)。
createDateTimeFromSystemTime() 函数returns 一个 DateTime 对象。它可以通用,也可以在 32 位系统下工作。通过$basis和$resolution的其他参数,该函数还可以处理其他时间戳(LabVIEW Timestamp, Mac Timestamp ..)
function createDateTimeFromSystemTime(
$time, //num.String, integer or float
$basis = '1601-1-1',
$resolution = 1.E-7,
$timeZone = 'UTC'
){
return date_create($basis.' UTC')
->modify(round($time * $resolution).' Seconds')
->setTimeZone(new DateTimeZone($timeZone));
}
如何使用 LDAP 时间戳:
$ldapTimestamp = "132497313049180481";
$dateTime = createDateTimeFromSystemTime($ldapTimestamp);
echo $dateTime->format('Y-m-d H:i:s T');
//2020-11-13 08:55:05 UTC
算法来源于此class.
我正在查询 MS LDAP,一些关于用户的日期字段具有这种值:132497313049180481
。
它似乎是 Windows FILETIME 格式,用于 LDAP 和 Active Directory 中的某些信息作为 timestamp.
如何将其转换成可读的日期?
这将Windows FILETIME(例如:132497313049180481
)转换为人类可读的日期时间(在此案例:“2020-11-13 08:55:04”)。
希望有用:
$filetime = "132497313049180481";
echo filetimeToStr($filetime); // Will display "2020-11-13 08:55:04"
function filetimeToStr($filetime){
date_default_timezone_set ("UTC"); //For a result not depending on server time zone.
$resp = (int)($filetime / 10000000); //Number of seconds since 1601-01-01.
$diff = 11644473600; //Number of seconds between FILETIME & Unix timestamp.
$resp = $resp - $diff; //Actual Unix timestamp matching your filetime.
$resp = date("Y-m-d H:i:s", $resp);
return $resp;
}
想知道 11644473600 来自哪里?
MSDN 说 FILETIME :
Contains a 64-bit value representing the number of 100-nanosecond intervals since January 1, 1601 (UTC). https://docs.microsoft.com/fr-be/windows/win32/api/minwinbase/ns-minwinbase-filetime?redirectedfrom=MSDN
关于 Unix 时间戳:
Unix epoch is the time 00:00:00 UTC on 1 January 1970 ... every day is treated as if it contains exactly 86400 seconds. https://en.wikipedia.org/wiki/Unix_time
date_default_timezone_set ("UTC"); //For a result not depending on server time zone.
$start_date = date_create("1601-01-01");
$end_date = date_create("1970-01-01");
$diff = date_diff($start_date, $end_date);
$diff = (int)$diff->format("%a"); //Number of days between FILETIME & Unix timestamp
$diff = ($diff * 86400); //Number of seconds between FILETIME & Unix timestamp
echo $diff; //Will display 11644473600
已编辑
为不依赖于服务器时区的结果添加了 date_default_timezone_set ("UTC");
(感谢 @jspit)。
createDateTimeFromSystemTime() 函数returns 一个 DateTime 对象。它可以通用,也可以在 32 位系统下工作。通过$basis和$resolution的其他参数,该函数还可以处理其他时间戳(LabVIEW Timestamp, Mac Timestamp ..)
function createDateTimeFromSystemTime(
$time, //num.String, integer or float
$basis = '1601-1-1',
$resolution = 1.E-7,
$timeZone = 'UTC'
){
return date_create($basis.' UTC')
->modify(round($time * $resolution).' Seconds')
->setTimeZone(new DateTimeZone($timeZone));
}
如何使用 LDAP 时间戳:
$ldapTimestamp = "132497313049180481";
$dateTime = createDateTimeFromSystemTime($ldapTimestamp);
echo $dateTime->format('Y-m-d H:i:s T');
//2020-11-13 08:55:05 UTC
算法来源于此class.