Mat*_*een 5 python datetime unit-testing python-2.7
我正在从Active Directory中提取信息,这意味着我正在处理一些COMObjects.其中一个日期存储为64位整数(实际上是两个32位整数).我已经想出如何使用以下代码将其更改为日期时间对象.
def convert_to_datetime(time_object):
# http://docs.activestate.com/activepython/2.6/pywin32/html/com/help/active_directory.html
d = 116444736000000000L #diference between 1601 and 1970
time_int = (((long(time_object.highpart) << 32) + long(time_object.lowpart)) - d)/10000000
return datetime.datetime.fromtimestamp(time_int)
Run Code Online (Sandbox Code Playgroud)
现在有了这个,我想为此建立一个单元测试.但是,我似乎无法弄清楚如何从datetime对象生成64位整数.我目前正在做的是我创建了一个复制COMObject的类,它将其值存储为两个32位整数,然后对匹配的日期和整数的值进行硬编码.但是,我想根据"现在"的时间创建这些值.
以下是单元测试当前的样子,即通过.
def test_convert_to_datetime_for_64bit_int_returns_value(self):
now_com_time = COMObjectDate(30375774,216380170)
self.assertEqual(datetime.datetime(2014, 6, 3, 14, 0, 13), AD_AG.convert_to_datetime(now_com_time))
class COMObjectDate:
def __init__(self, high, low):
self.highpart = high
self.lowpart = low
Run Code Online (Sandbox Code Playgroud)
有没有办法从datetime对象生成两个32位值?
旁注:我意识到我可能已经过度思考了一些,因为我的单元测试确实通过了但是我宁愿没有硬编码值,因此测试更强大而且不依赖于"正常工作"的值.
我们将从您链接到的文档中的引用开始:
Active Directory 中的时间存储在 64 位整数中,该整数跟踪自 1601 年 1 月 1 日以来经过的 100 纳秒间隔数。
因此,将这些部分视为两个 32 位整数(高位和低位,添加前导零):
bin(30375774) =
00000001110011110111111101011110
bin(216380170) =
00001100111001011011001100001010
Run Code Online (Sandbox Code Playgroud)
将它们连接在一起(“高位部分”和“低位部分”)以获得 64 位整数:
0000000111001111011111110101111000001100111001011011001100001010
Run Code Online (Sandbox Code Playgroud)
以十进制表示,即130462956137067274.
要获取自 1601 年 1 月 1 日以来经过的秒数,我们必须除以
10000000。
130462956137067274 / 10000000
= 13.046.295.613 seconds since the 1st of january 1601
Run Code Online (Sandbox Code Playgroud)
如果您希望构造相应的 32 位整数部分,简单的日期算术应该能让您得到相反的结果:从 1601 年 1 月 1 日以来的秒数开始,乘以 10000000 并将 64 位整数分成两个 32 位部分(其中可以通过位移位轻松完成)。
方法convert_to_datetime的实现也应该有意义。现在您唯一需要的是该datetime.fromtimestamp()方法需要一个POSIX timestampepoch ,它是一个浮点数(在本例中),包含自(1970 年 1 月 1 日)以来经过的秒数。这解释了方法主体中存在的基于偏移的计算。
====> 1. Creating a Unix timestamp (seconds since epoch) from a datetime
>>> import time
>>> import datetime
>>> time.mktime(datetime.datetime.now().timetuple())
1401828155.0
====> 2. Adding the difference in seconds between 01/01/1601 and 01/01/1970
====> (11644473600 seconds)
>>> 11644473600 + 1401828155
13046301755
====> 3. Multiply by 10000000
>>> 13046301755 * 10000000
130463017550000000
====> 4. Interpret as binary. Add leading zero's until you have 64 bits.
>>> bin(130463017550000000)
'0b111001111011111110110110001011001011001001010111110000000'
====> 5. Split the high part (32 bits) and the low part (32 bits)
>>> ...
Run Code Online (Sandbox Code Playgroud)