7

我有一个在 linux 机器上运行的 Intranet,它通过 PHP 使用 LDAP 对 Windows 机器上的 Active Directory 进行身份验证。

我可以使用 LDAP 从 AD 检索用户条目,并从 php 数组访问上次登录日期,例如:

echo $adAccount['lastlogontimestamp'][0]; // returns something like 129802528752492619

如果这是一个 Unix 时间戳,我将使用以下 PHP 代码转换为人类可读的日期:

date("d-m-Y H:i:s", $lastlogontimestamp);

但是,这不起作用。有谁知道我怎样才能做到这一点,或者确实可以从 Linux 机器上做到这一点?

4

2 回答 2

18

据此您拥有的 windows 时间戳是自 1601 年 1 月 1 日以来的 100-ns 数。因此,您可以使用以下公式将其转换为 unix 时间戳:

tUnix = tWindow/(10*1000*1000)-11644473600;

您除以10*1000*1000转换为自 1601 年 1 月 1 日以来的秒数,然后折扣11644473600是 1601 年 1 月和 1970 年 1 月(unix 时间)之间的秒数。

所以在 PHP 中:

date("d-m-Y H:i:s", $lastlogontimestamp/10000000-11644473600);

编辑:有趣的是,我得到的偏移量与 Baba 不同。我用Java得到了我的:

Calendar date1 = Calendar.getInstance(); date1.set(1601, 1, 1);
Calendar date2 = Calendar.getInstance(); date2.set(1970, 1, 1);
long dt = date2.getTimeInMillis() - date1.getTimeInMillis();
System.out.println(String.format("%f", dt / 1000.0)); // prints "11644473600.000000"

根据这个 SO:将 Unix/Linux 时间转换为 Windows 时间的方法,我的偏移量是正确的。

于 2012-05-02T10:47:17.167 回答
6

由于 windows 不是以秒为单位,但nano seconds您需要将其除以四舍五入,10000000因为1601-01-01 and 1970-01-01windows 时间戳从1601-01-01

function convertWindowsTimestamp($wintime) {
   return $wintime / 10000000 - 11644477200;
}

$lastlogontimestamp = convertWindowsTimestamp("129802528752492619");
$date = date("d-m-Y H:i:s", $lastlogontimestamp);
var_dump($date);

输出

string '30-04-2012 10:47:55' (length=19)
于 2012-05-02T10:40:29.563 回答