我想以NT格式创建网络时间戳。
我已经能够使用此功能将它们转换为可读时间:
NetworkStamp = "\xc0\x65\x31\x50\xde\x09\xd2\x01"
def GetTime(NetworkStamp):
Ftime = int(struct.unpack('<Q',NetworkStamp)[0])
Epoch = divmod(Ftime - 116444736000000000, 10000000)
Actualtime = datetime.datetime.fromtimestamp(Epoch[0])
return Actualtime, Actualtime.strftime('%Y-%m-%d %H:%M:%S')
print GetTime(NetworkStamp)
输出:
(datetime.datetime(2016, 9, 8, 11, 35, 57), '2016-09-08 11:35:57')
现在我想做相反的事情,将'2016/09/08 11:35:57'
秒转换为这种格式:
"\xc0\x65\x31\x50\xde\x09\xd2\x01"
答案 0 :(得分:2)
如果你理解如何在一个方向上执行转换,那么反向执行它基本上是以相反的顺序使用每个方法的逆。只需查看您正在使用的模块/类的文档:
strftime
有a strptime
counterpart fromtimestamp
is matched by timestamp
(如果您使用的是3.3之前的Python,timestamp
不存在,但您可以在函数外部定义FILETIME_epoch = datetime.datetime(1601, 1, 1) - datetime.timedelta(seconds=time.altzone if time.daylight else time.timezone)
以预先计算{ {1}}代表您所在时区的datetime
纪元,然后使用FILETIME
直接从int((mydatetime - FILETIME_epoch).total_seconds())
纪元获得int
秒,而无需手动调整{{1}之间的差异和Unix epoches分开)FILETIME
(你真的不需要,因为你只使用商,而不是余数,你只能做FILETIME
并避免以后编制索引)是平凡可逆的(只需乘法和加法) ,如果你使用我的技巧直接从#2转换为divmod
纪元秒,则不需要添加Epoch = (Ftime - 116444736000000000) // 10000000
is matched by struct.pack
我没有提供确切的代码,因为你真的应该学会自己使用这些东西(并在必要时阅读文档);我猜你的前进代码是在没有理解它正在做什么的情况下编写的,因为如果你理解它,反过来应该是显而易见的;每一步都在同一页上有反向记录。
答案 1 :(得分:1)
将Window的FILETIME
值转换为datetime.datetime
的代码不尽可能准确 - 它会截断可能存在的任何小数秒(因为它会忽略{的剩余部分{1}}结果)。这在您的代码创建的可读字符串中并不明显,因为它只显示整秒
即使包含小数秒,您也无法完全按照自己的意愿行事,因为Windows divmod()
结构的值间隔为100纳秒(.1微秒),但Python的FILETIME
仅支持准确性到整个微秒。因此,即使进行最准确的转换,由于所涉及的信息丢失,最好的可能是接近原始值。
这是Python 2和3的代码,使用问题中的datetime
测试值来证明这一点:
NetworkStamp
输出:
import datetime
import struct
import time
WINDOWS_TICKS = int(1/10**-7) # 10,000,000 (100 nanoseconds or .1 microseconds)
WINDOWS_EPOCH = datetime.datetime.strptime('1601-01-01 00:00:00',
'%Y-%m-%d %H:%M:%S')
POSIX_EPOCH = datetime.datetime.strptime('1970-01-01 00:00:00',
'%Y-%m-%d %H:%M:%S')
EPOCH_DIFF = (POSIX_EPOCH - WINDOWS_EPOCH).total_seconds() # 11644473600.0
WINDOWS_TICKS_TO_POSIX_EPOCH = EPOCH_DIFF * WINDOWS_TICKS # 116444736000000000.0
def get_time(filetime):
"""Convert windows filetime winticks to python datetime.datetime."""
winticks = struct.unpack('<Q', filetime)[0]
microsecs = (winticks - WINDOWS_TICKS_TO_POSIX_EPOCH) / WINDOWS_TICKS
return datetime.datetime.fromtimestamp(microsecs)
def convert_back(timestamp_string):
"""Convert a timestamp in Y=M=D H:M:S.f format into a windows filetime."""
dt = datetime.datetime.strptime(timestamp_string, '%Y-%m-%d %H:%M:%S.%f')
posix_secs = int(time.mktime(dt.timetuple()))
winticks = (posix_secs + int(EPOCH_DIFF)) * WINDOWS_TICKS
return winticks
def int_to_bytes(n, minlen=0): # helper function
""" int/long to bytes (little-endian byte order).
Note: built-in int.to_bytes() method could be used in Python 3.
"""
nbits = n.bit_length() + (1 if n < 0 else 0) # plus one for any sign bit
nbytes = (nbits+7) // 8 # number of whole bytes
ba = bytearray()
for _ in range(nbytes):
ba.append(n & 0xff)
n >>= 8
if minlen > 0 and len(ba) < minlen: # zero pad?
ba.extend([0] * (minlen-len(ba)))
return ba # with low bytes first
def hexbytes(s): # formatting helper function
"""Convert string to string of hex character values."""
ba = bytearray(s)
return ''.join('\\x{:02x}'.format(b) for b in ba)
win_timestamp = b'\xc0\x65\x31\x50\xde\x09\xd2\x01'
print('win timestamp: b"{}"'.format(hexbytes(win_timestamp)))
dtime = get_time(win_timestamp)
readable = dtime.strftime('%Y-%m-%d %H:%M:%S.%f') # includes fractional secs
print('datetime repr: "{}"'.format(readable))
winticks = convert_back(readable) # includes fractional secs
new_timestamp = int_to_bytes(winticks)
print('new timestamp: b"{}"'.format(hexbytes(new_timestamp)))
答案 2 :(得分:-1)
基本转换:
from datetime import datetime
from calendar import timegm
EPOCH_AS_FILETIME = 116444736000000000 # January 1, 1970 as MS file time
HUNDREDS_OF_NANOSECONDS = 10000000
def dt_to_filetime(dt):
return EPOCH_AS_FILETIME + (timegm(dt.timetuple()) * HUNDREDS_OF_NANOSECONDS)
答案基于我发现的要点:https://gist.github.com/Mostafa-Hamdy-Elgiar/9714475f1b3bc224ea063af81566d873
要点增加了对时区和转换的支持。