在Windows下使用python修改文件创建/访问/写入时间戳 [英] Modify file create / access / write timestamp with python under windows

查看:80
本文介绍了在Windows下使用python修改文件创建/访问/写入时间戳的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我试图找到一种使用python在Windows下修改文件时间戳的简单方法,但是网络上没有很多明确的信息.经过一会儿搜索,我找到了解决方案.为了缩短对其他人的搜索,代码如下.

它可以做得更简单,更漂亮,但可以.我唯一没有解决的是夏季时间-冬季时间问题,即如果给出了夏季时间,则结果相差一小时.也许有人可以添加更正?

from win32file import CreateFile, SetFileTime, GetFileTime, CloseHandle 
from win32file import GENERIC_READ, GENERIC_WRITE, OPEN_EXISTING
from pywintypes import Time
import time

import sys
import os

if len(sys.argv)<5:
  pfile = os.path.basename(sys.argv[0])
  print "USAGE:\n\t%s <createTime> <modifyTime> <accessTime> <FileName>\n" % pfile
  print "EXAMPLE:"
  print '%s "01.01.2000 00:00:00" "01.01.2000 00:00:00" "01.01.2000 00:00:00" file' % (pfile) 
  sys.exit()  

# get arguments  
cTime = sys.argv[1] # create
mTime = sys.argv[2] # modify
aTime = sys.argv[3] # access
fName = sys.argv[4]

# specify time format
format = "%d.%m.%Y %H:%M:%S"
offset = 0 # in seconds

# create struct_time object
cTime_t = time.localtime(time.mktime(time.strptime(cTime,format))+offset)
mTime_t = time.localtime(time.mktime(time.strptime(mTime,format))+offset)
aTime_t = time.localtime(time.mktime(time.strptime(aTime,format))+offset)

# visually check if conversion was ok
print
print "FileName: %s" % fName
print "Create  : %s --> %s OK" % (cTime,time.strftime(format,cTime_t))
print "Modify  : %s --> %s OK" % (mTime,time.strftime(format,mTime_t))
print "Access  : %s --> %s OK" % (aTime,time.strftime(format,aTime_t))
print

# change timestamp of file
fh = CreateFile(fName, GENERIC_READ | GENERIC_WRITE, 0, None, OPEN_EXISTING, 0, 0) 
createTime, accessTime, modifyTime = GetFileTime(fh) 
print "Change Create from",createTime,"to %s" % (time.strftime(format,cTime_t))
print "Change Modify from",modifyTime,"to %s" % (time.strftime(format,mTime_t))
print "Change Access from",accessTime,"to %s" % (time.strftime(format,aTime_t))
print

createTime = Time(time.mktime(cTime_t))
accessTime   = Time(time.mktime(aTime_t))
modifyTime    = Time(time.mktime(mTime_t))
SetFileTime(fh, createTime, accessTime, modifyTime) 
CloseHandle(fh)

# check if all was ok
ctime = time.strftime(format,time.localtime(os.path.getctime(fName)))
mtime = time.strftime(format,time.localtime(os.path.getmtime(fName)))
atime = time.strftime(format,time.localtime(os.path.getatime(fName)))

print "CHECK MODIFICATION:"
print "FileName: %s" % fName
print "Create  : %s" % (ctime)
print "Modify  : %s" % (mtime)
print "Access  : %s" % (atime)

解决方案

在两个地方,您可能需要校正一小时的冬夏差异.在这两种情况下,我们都使用tm_isdst字段,time.localtime可以方便地计算该字段以告诉我们夏令时(DST)是否在特定时间戳上有效.

输入校正

如果您要在夏季设置冬季时间戳,反之亦然,除非您在致电SetFileTime之前进行补偿,否则它将在匹配季节到来时减少一个小时.

now = time.localtime()
createTime = Time(time.mktime(cTime_t) + 3600 * (now.tm_isdst - cTime_t.tm_isdst))
accessTime = Time(time.mktime(aTime_t) + 3600 * (now.tm_isdst - aTime_t.tm_isdst))
modifyTime = Time(time.mktime(mTime_t) + 3600 * (now.tm_isdst - mTime_t.tm_isdst))
SetFileTime(fh, createTime, accessTime, modifyTime) 

输出校正

要使Python报表与Windows资源管理器匹配,请在调用strftime之前应用更正:

# check if all was ok
now = time.localtime()
ctime = os.path.getctime(fName)
mtime = os.path.getmtime(fName)
atime = os.path.getatime(fName)
ctime += 3600 * (now.tm_isdst - time.localtime(ctime).tm_isdst)
mtime += 3600 * (now.tm_isdst - time.localtime(mtime).tm_isdst)
atime += 3600 * (now.tm_isdst - time.localtime(atime).tm_isdst)
ctime = time.strftime(format,time.localtime(ctime))
mtime = time.strftime(format,time.localtime(mtime))
atime = time.strftime(format,time.localtime(atime))

两个更正

当心,如果您同时使用这两种方法,那么您的Python输出似乎将再次与您的输入不匹配.这可能是可取的(请参阅下文),但如果它困扰您,

  • 如果您希望时间戳看起来恰好是一年中的本机时间,则仅选择输入校正.
  • 如果您习惯于看到DST生效后它们每年两次跳跃一次,然后消失,则仅选择输出校正.

为什么DST如此不一致?

Python和Windows选择了不同的方法来在UTC和本地时区之间转换时间戳:

  • Python使用时间戳上有效的DST代码.通过这种方式,时间戳全年都具有一致的表示形式.

  • Windows现在使用有效的DST代码.这样,所有显示的时间戳都具有相同的隐式代码.

这很明显,如果您使用'%Z'在转换后的字符串中包含时区(例如,PST与PDT),但是由于大多数应用程序(包括Windows资源管理器)都没有,因此一小时的明显不一致可以清单.

示例

用明确的时间代码打印时,很明显每列中的标记确实都代表同一时刻:

File #1 (January)        File #2 (June)
2000-01-30 20:00:00 UTC  2000-06-22 20:00:00 UTC

observed in January in California:
2000-01-30 12:00:00 PST  2000-06-30 13:00:00 PDT  [Python]
2000-01-30 12:00:00 PST  2000-06-30 12:00:00 PST  [Windows]

observed in June in California:
2000-01-30 12:00:00 PST  2000-06-30 13:00:00 PDT  [Python]
2000-01-30 13:00:00 PDT  2000-06-30 13:00:00 PDT  [Windows]

observed in June in New York:
2000-01-30 15:00:00 EST  2000-06-30 16:00:00 EDT  [Python]
2000-01-30 16:00:00 EDT  2000-06-30 16:00:00 EDT  [Windows]

如果我们可以要求strftime遵守tm_isdst字段,以匹配Windows Explorer和大多数其他显示文件时间戳记的应用程序,那将是很好的选择,但是至少有一个简单的解决方法可以自己进行计算.

def adjustForDST (seconds):
    now = time.localtime()
    correction = 60*60 * (now.tm_isdst - time.localtime(seconds).tm_isdst)
    return seconds + correction

time.strftime(format, time.localtime(adjustforDST(mtime)))

来源:

http://bytes.com/topic /python/answers/655606-python-2-5-1-broken-os-stat-module http://search.cpan.org/~shay/Win32-UTCFileTime- 1.58/lib/Win32/UTCFileTime.pm

如果cpan链接因新版本而再次中断,请按照以下方式找到它:

https://www.google.com/search?q=UTCFileTime.pm

I tried to find an easy way to modifiy a file timestamp under windows using python, but there was not much clear information on the web. After searching a while I got a solution. To shorten the search for others, the code follows here.

It might be done easier and more beautiful, but it works. The only thing I didn't solve is the summer time - winter time issue, i.e. if a time in summer is given, the result differs by one hour. Maybe someone can add a correction?

from win32file import CreateFile, SetFileTime, GetFileTime, CloseHandle 
from win32file import GENERIC_READ, GENERIC_WRITE, OPEN_EXISTING
from pywintypes import Time
import time

import sys
import os

if len(sys.argv)<5:
  pfile = os.path.basename(sys.argv[0])
  print "USAGE:\n\t%s <createTime> <modifyTime> <accessTime> <FileName>\n" % pfile
  print "EXAMPLE:"
  print '%s "01.01.2000 00:00:00" "01.01.2000 00:00:00" "01.01.2000 00:00:00" file' % (pfile) 
  sys.exit()  

# get arguments  
cTime = sys.argv[1] # create
mTime = sys.argv[2] # modify
aTime = sys.argv[3] # access
fName = sys.argv[4]

# specify time format
format = "%d.%m.%Y %H:%M:%S"
offset = 0 # in seconds

# create struct_time object
cTime_t = time.localtime(time.mktime(time.strptime(cTime,format))+offset)
mTime_t = time.localtime(time.mktime(time.strptime(mTime,format))+offset)
aTime_t = time.localtime(time.mktime(time.strptime(aTime,format))+offset)

# visually check if conversion was ok
print
print "FileName: %s" % fName
print "Create  : %s --> %s OK" % (cTime,time.strftime(format,cTime_t))
print "Modify  : %s --> %s OK" % (mTime,time.strftime(format,mTime_t))
print "Access  : %s --> %s OK" % (aTime,time.strftime(format,aTime_t))
print

# change timestamp of file
fh = CreateFile(fName, GENERIC_READ | GENERIC_WRITE, 0, None, OPEN_EXISTING, 0, 0) 
createTime, accessTime, modifyTime = GetFileTime(fh) 
print "Change Create from",createTime,"to %s" % (time.strftime(format,cTime_t))
print "Change Modify from",modifyTime,"to %s" % (time.strftime(format,mTime_t))
print "Change Access from",accessTime,"to %s" % (time.strftime(format,aTime_t))
print

createTime = Time(time.mktime(cTime_t))
accessTime   = Time(time.mktime(aTime_t))
modifyTime    = Time(time.mktime(mTime_t))
SetFileTime(fh, createTime, accessTime, modifyTime) 
CloseHandle(fh)

# check if all was ok
ctime = time.strftime(format,time.localtime(os.path.getctime(fName)))
mtime = time.strftime(format,time.localtime(os.path.getmtime(fName)))
atime = time.strftime(format,time.localtime(os.path.getatime(fName)))

print "CHECK MODIFICATION:"
print "FileName: %s" % fName
print "Create  : %s" % (ctime)
print "Modify  : %s" % (mtime)
print "Access  : %s" % (atime)

解决方案

There are two places where you might want to correct for winter/summer difference of one hour. In both cases, we make use of the tm_isdst field, which time.localtime conveniently calculates to tell us whether Daylight Savings Time (DST) was in effect for a particular timestamp.

Input Correction

If you are setting a winter timestamp during summer, or vice versa, it will become off by an hour when its matching season comes around unless you compensate before calling SetFileTime:

now = time.localtime()
createTime = Time(time.mktime(cTime_t) + 3600 * (now.tm_isdst - cTime_t.tm_isdst))
accessTime = Time(time.mktime(aTime_t) + 3600 * (now.tm_isdst - aTime_t.tm_isdst))
modifyTime = Time(time.mktime(mTime_t) + 3600 * (now.tm_isdst - mTime_t.tm_isdst))
SetFileTime(fh, createTime, accessTime, modifyTime) 

Output Correction

To make Python reports match Windows Explorer, we apply the correction before calling strftime:

# check if all was ok
now = time.localtime()
ctime = os.path.getctime(fName)
mtime = os.path.getmtime(fName)
atime = os.path.getatime(fName)
ctime += 3600 * (now.tm_isdst - time.localtime(ctime).tm_isdst)
mtime += 3600 * (now.tm_isdst - time.localtime(mtime).tm_isdst)
atime += 3600 * (now.tm_isdst - time.localtime(atime).tm_isdst)
ctime = time.strftime(format,time.localtime(ctime))
mtime = time.strftime(format,time.localtime(mtime))
atime = time.strftime(format,time.localtime(atime))

Both Corrections

Beware, if you apply both, your Python output will again seem to mismatch your input. This may be desirable (see below), but if it bothers you:

  • Choose only Input Correction if you prefer timestamps that look right at their native time of year.
  • Choose only Output Correction if you're used to seeing them jump an hour twice a year as DST takes effect and then goes away.

Why is DST so inconsistent?

Python and Windows have chosen different methods to convert timestamps between UTC and the local time zone:

  • Python uses the DST code that was in effect at the timestamp. This way, the time stamp has a consistent representation year-round.

  • Windows uses the DST code in effect right now. This way, all time stamps shown have the same implicit code.

This is evident if you use '%Z' to include the time zone in the converted string (PST vs. PDT, for example) but since most apps (including Windows Explorer) do not, an apparent one-hour inconsistency can manifest.

Example

When printed with explicit time codes, it becomes clear that the stamps in each column really do all represent the same instant in time:

File #1 (January)        File #2 (June)
2000-01-30 20:00:00 UTC  2000-06-22 20:00:00 UTC

observed in January in California:
2000-01-30 12:00:00 PST  2000-06-30 13:00:00 PDT  [Python]
2000-01-30 12:00:00 PST  2000-06-30 12:00:00 PST  [Windows]

observed in June in California:
2000-01-30 12:00:00 PST  2000-06-30 13:00:00 PDT  [Python]
2000-01-30 13:00:00 PDT  2000-06-30 13:00:00 PDT  [Windows]

observed in June in New York:
2000-01-30 15:00:00 EST  2000-06-30 16:00:00 EDT  [Python]
2000-01-30 16:00:00 EDT  2000-06-30 16:00:00 EDT  [Windows]

It would be nice if we could ask strftime to honor the tm_isdst field, to match Windows Explorer and most other apps that display file timestamps, but at least there's a simple workaround to do the calculation ourselves.

def adjustForDST (seconds):
    now = time.localtime()
    correction = 60*60 * (now.tm_isdst - time.localtime(seconds).tm_isdst)
    return seconds + correction

time.strftime(format, time.localtime(adjustforDST(mtime)))

Sources:

http://bytes.com/topic/python/answers/655606-python-2-5-1-broken-os-stat-module http://search.cpan.org/~shay/Win32-UTCFileTime-1.58/lib/Win32/UTCFileTime.pm

If the cpan link breaks again with a new revision, find it this way:

https://www.google.com/search?q=UTCFileTime.pm

这篇关于在Windows下使用python修改文件创建/访问/写入时间戳的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆