与微软合作';Java中的s Integer8/LargeInteger?
我正在通过LDAP使用AD(使用SpringLDAP),在使用Integer8/LargeInteger作为时间戳时遇到了一个奇怪的问题。也就是说,我尝试写入该类型的字段导致 格式不正确的“此处字段名”属性值 我试着使用long和string,希望底层的实现可以进行任何必要的转换,但是运气不好。这是我如何做我的数学与微软合作';Java中的s Integer8/LargeInteger?,java,active-directory,ldap,Java,Active Directory,Ldap,我正在通过LDAP使用AD(使用SpringLDAP),在使用Integer8/LargeInteger作为时间戳时遇到了一个奇怪的问题。也就是说,我尝试写入该类型的字段导致 格式不正确的“此处字段名”属性值 我试着使用long和string,希望底层的实现可以进行任何必要的转换,但是运气不好。这是我如何做我的数学 /* AD Keeps track of time in 100 NS intervals (UTC) since Jan 1st 1601 */ long winEpocMS
/* 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 LIB来处理读/写这些非常奇怪的时间值
任何能够解释为什么我们需要100纳秒分辨率的64位时间戳的人都可以获得额外的积分。我不知道有哪一个Java库可以用微软特有的格式处理时间(从1601年起,间隔为100纳秒)。我认为这是正确的。
您可以将
winEpocMS
定义为常数并使用:
long winTime100NS=(System.currentTimeMillis()-winEpocMS)*10000L代码>
我们需要64位时间戳的原因很简单。使用32位,您可以得到2^32个值(大约4000000000),足以处理从1970年到2038年的秒数(在Unix上称为2000年效应)。如果需要微秒或100纳秒的精度,可以使用更大的值,这些值必须作为64位数字进行管理。Java使用自1970年以来的毫秒来表示日期,并且需要long
类型,该类型是有符号的64位数字。好的,下面是详细信息
/* 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 1164444736000000000
134774 00:00:00.0000000 - 12/31/1969
下午6:00:00(当地时间)
最后,在使用AD时,确保字段接受任何值。有些字段使用“-1”表示“现在”,而“0”可能有特殊含义。此外,在某些情况下,时间属性修改是否与其他属性修改(如pwdLastSet和unicodePwd)捆绑在一起似乎很重要
最后一点,除非你知道自己的时区正确(很容易搞乱),否则我会避免使用GregoriaCalendar。在我的cod中,e winEpocMS是一个常数,我只是这样写以便于阅读。您对64位时间戳的评论有点不尽如人意;为什么100纳秒而不是更标准的毫秒?最后,你没有回答我的核心问题,为什么AD不接受长值?测量时间的100纳秒间隔是一个设计决定。在MS中,world似乎很常见,就像在.NETDateTime中一样。Ticks
以100纳秒的间隔测量时间。毫秒是Java的选择,任何这样的决定都有利弊(DateTime
在C#中是一个结构,因此不为null,而在Java中是一个类,可以为null,这在管理日期时有利弊)。为什么不接受长期价值对我来说是未知的。