2011-03-03 2 views
3

Je travaille avec AD via LDAP (en utilisant Spring LDAP) et j'ai rencontré un problème étrange en travaillant avec Integer8/LargeInteger comme timestamps outlined here. A savoir, mes tentatives d'écriture des champs de ce type ont donné lieu à ...Travailler avec Integer8/LargeInteger de MS en Java?

« nom du champ » ici malformée valeur d'attribut

J'ai essayé de mettre des chaînes et désire ardemment dans l'espoir que le sous-jacent l'implémentation ferait les conversions nécessaires mais pas de chance. Voici comment je fais mes maths ...

/* AD Keeps track of time in 100 NS intervals (UTC) since Jan 1st 1601 */ 
long winEpocMS = new GregorianCalendar(1601, Calendar.JANUARY, 1).getTimeInMillis();   
long nowMS  = System.currentTimeMillis(); 
long winTime100NS = (nowMS - winEpocMS) * 10000; 

Existe-t-il un moyen facile/élégant d'emballer ces données correctement? Existe-t-il des librairies Java pré-construites pour gérer la lecture/écriture de ces valeurs de temps plutôt bizarres? Le point bonus permet à quiconque d'expliquer pourquoi nous avons besoin d'un horodatage 64 bits à la résolution 100NS.

Répondre

3

oks ici la ventilation ...

/* time since Jan 1st 1601 00:00:00 UTC */ 
final long WIN_EPOC_MS = 11644473600000L; 
final long now_ms  = System.currentTimeMillis(); 
final long now_win_ns = (now_ms + WIN_EPOC_MS) * 10000L; 

L'inverse devrait être évident à partir du code ci-dessus. Si vous voulez vérifier les conversions, utilisez w32tm. Par exemple, les spectacles suivants que nous avons le bon moment de convertion au EPOC Unix (notez que je suis dans CST)

w32tm/ntte 116444736000000000
134774 00: 00: 00,0000000 - 31/12/1969 06:00:00 h (heure locale)

Enfin, lorsque vous travaillez avec AD assurez-vous que le champ accepte une valeur. Certains champs prennent "-1" pour signifier "maintenant" et "0" peut avoir une signification particulière. En outre, dans certains cas, il semble important que la modification de l'attribut de temps soit associée à d'autres modifications d'attributs (telles que pwdLastSet et unicodePwd). Une dernière note, j'éviterais GregorianCalendar à moins que vous sachiez que vous avez bien vos fuseaux horaires (il est facile de gâcher).

1

Je ne connais aucune bibliothèque Java qui gère l'heure avec ce format spécifique à Microsoft (intervalles de 100 nanosecondes depuis 1601). Je pense que cette façon est correcte.
Vous pouvez définir winEpocMS comme une constante et l'utilisation:

long winTime100NS = (System.currentTimeMillis() - winEpocMS) * 10000L;

Pourquoi nous avons besoin timestamp 64bit est simple. Avec 32bit vous avez 2^32 valeurs (environ 4 000 000 000), assez pour gérer les secondes depuis 1970 jusqu'en 2038 (connu sous le nom de l'effet de 2000 ans sur Unix). Si vous avez besoin d'une précision de microsecondes ou de 100 nanosecondes, vous utilisez des valeurs plus grandes qui doivent être gérées comme des nombres de 64 bits. Java utilise des millisecondes depuis 1970 pour représenter les dates et requiert le type long qui est un nombre 64 bits signé.

+0

dans ma morue, e winEpocMS est une constante, je l'ai juste écrit comme ça pour faciliter la lecture. Votre commentaire sur les horodatages 64 bits laisse un peu à désirer; pourquoi 100 ns au lieu de ms qui est beaucoup plus standard? Enfin, vous ne répondez pas au noyau de ma question, pourquoi AD n'accepte-t-elle pas la valeur longue? –

+0

Un intervalle de 100 nanosecondes pour mesurer le temps est une décision de conception. Dans le monde MS semble être habituel, comme dans .NET 'DateTime.Ticks' mesure le temps dans des intervalles de 100 nanosecondes.Millisecondes est le choix de Java, et toute décision comme celle-ci a des avantages et des inconvénients ('DateTime' est une structure en C# et donc pas nulle, alors que Java est une classe et peut être nulle, cela a des avantages et des inconvénients. Pourquoi n'accepte pas la valeur longue est inconnu pour moi. –

Questions connexes