2011-03-03 34 views
3

我正在通过LDAP(使用Spring LDAP)与AD协同工作,并且在处理Integer8/LargeInteger作为outlined here的时间戳时遇到了一个奇怪的问题。也就是说,我试图写该类型的领域都造成了...在Java中使用MS的Integer8/LargeInteger?

畸形“这里字段名称”属性值

我试图把长材和字符串在希望的根本实施将做任何需要的转换,但没有运气。这是我如何做我的数学...

/* 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; 

是否有一个简单/优雅的方式来正确打包这些数据?是否有预编译的Java库来处理读取/写入这些相当奇怪的时间值?

加分指向任何人,可以解释为什么我们需要在100NS分辨率的64位时间戳。

回答

3

确定这里是击穿...

/* 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; 

相反应该是明显从上面的代码。如果你想仔细检查转换使用w32tm。例如,下面显示的是我们有正确的皈依时间Unix的EPOC(请注意,我在CST)

W32TM/ntte 116444736000000000
134774 00:00:00.0000000 - 1969年12月31日 下午6时00分零零秒(当地时间)

最后,AD工作时确保现场接受任何值。有些字段取“-1”表示“now”和“0”可能有特殊含义。此外,在某些情况下,如果时间属性修改与其他属性修改(如pwdLastSet和unicodePwd)捆绑在一起似乎很重要。

最后一个注意事项,我会避免GregorianCalendar,除非你知道你的时区是正确的(这很容易搞砸)。

1

我不知道任何处理该特定于Microsoft的格式(自1601年以来的间隔为100纳秒)的Java库。我认为这种方式是正确的。我们为什么需要64位时间戳是简单

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


您可以定义winEpocMS为常数和使用。在32位的情况下,你可以得到2^32的值(大约40,000,000,000),足以处理1970年以来的秒数,直到2038年(对Unix有2000年的影响)。如果您需要微秒或100纳秒精度,则需要使用更大的值,必须将其作为64位数进行管理。 Java自1970年以来使用毫秒来表示日期,并且需要long类型,它是有符号的64位数字。

+0

在我的鳕鱼,e winEpocMS是一个常数,我只是这样写的,以便于阅读。您对64位时间戳的评论稍微有些偏差;为什么100纳秒,而不是毫秒,这是更标准?最后,你不回答核心我的问题,为什么不接受长期价值? – 2011-03-03 20:15:21

+0

用于测量时间的100纳秒间隔是设计决定。在MS世界中似乎很平常,如在.NET中'DateTime.Ticks'以100纳秒为间隔测量时间。毫秒是Java的选择,像这样的任何决定都有优点和缺点('DateTime'是C#中的一个结构体,因此不是null,而Java中是一个类,可以为null,这在管理日期时有利有弊。为什么不接受长期价值对我来说是未知的。 – 2011-03-03 20:22:54