2012-05-02 24 views
5

Mam intranet działający na systemie Linux, który uwierzytelnia się z Active Directory na pudełku Windows, używając LDAP poprzez PHP.Konwertuj datownik Windows do tej pory za pomocą PHP na Linuksie Box

mogę odzyskać pozycję użytkownika z AD przy użyciu protokołu LDAP i dostęp ostatnią datę logowania z np tablicy PHP:

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

Jeśli to był timestamp Unix chciałbym użyć następującego kodu PHP do konwersji na ludzka czytelna data:

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

To jednak nie działa. Czy ktoś wie, w jaki sposób mogę to osiągnąć, a nawet jeśli jest to możliwe z systemu Linux?

Odpowiedz

10

Zgodnie z this, znacznik czasu Windows, który tam masz, jest liczbą 100-ns od 1 stycznia 1601. Dlatego możesz po prostu przekonwertować go do uni x datownik za pomocą następującego wzoru:

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

podzielić przez 10*1000*1000 przekonwertować sekund od Jan 1 1601 a następnie dyskontować 11644473600 który jest liczba sekund pomiędzy stycznia 1601 i stycznia 1970 (czasu UNIX).

Więc w PHP:

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

EDIT: Co ciekawe, mam inny niż przesunięcie Baby. Mam kopalni z 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" 

Zgodnie z tym SO: Ways to Convert Unix/Linux time to Windows time mój offset jest poprawny.

+3

Mam inne przesunięcie z PHP: strtotime ("1601-01-01") - strtotime ("1970-01-01") = 11644470000. Jest to godzina (3600 sekund) różna od twojej, ale jako MSDN mówi, że do używania wartości pochodzącej z języka Java użyję twojej odpowiedzi. Dziękuję za pomoc i dziękuję Babie. – amburnside

+1

Widziałem też 11644477200 (jak używał Baba). To co najmniej trzy różne wartości. Oczywiście różnica nie jest ogromna i może nie mieć znaczenia w niektórych kontekstach, ale dobrze jest wiedzieć, jaka powinna być wartość odejmowana, niezależnie od strefy czasowej. Idę do wartości '... 7360 ...' jako [widoczne w MSDN] (http://msdn.microsoft.com/en-us/library/ms724228). – Synetech

+0

@Synetech Tak, cała rzecz na randce to krwawy bałagan. To zawsze zależy od tego, z którego systemu korzystasz. – brimborium

3

Ponieważ Windows nie jest w sekundach, ale w nano seconds trzeba zaokrąglić go poprzez podzielenie go przez 10000000 trzeba także usunąć sekund między 1601-01-01 and 1970-01-01 od początku okna datownika z 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); 

Output

string '30-04-2012 10:47:55' (length=19) 
+0

Czy możesz wyjaśnić, co robi twoja funkcja, czyli dlaczego podzielić przez 10 milionów, a następnie odjąć 11644477200? – amburnside

+0

dodane exaplanation – Baba

Powiązane problemy