473,721 Members | 2,133 Online
Bytes | Software Development & Data Engineering Community
+ Post

Home Posts Topics Members FAQ

Daylight savings and getmtime

Qvx
Hello,

I'we written a simple web deployment program which scans for the
changes made to local copy of web site. Changed files are than
packaged into a zip file and deployed to web server.

Now here's the catch. Changes are computed using (1) log file from the
last deployment and (2) local file system. Log file contains
datestamps (integers) returned from os.path.getmtim e(f) function at
the time of last deployment. So i'm comparing two getmtime() values.
The problem is when Daylight saving kicks in: suddenly all local files
are reported as older than they were at the time of deployment.

How do I compensate for this?

Thanks,
Tvrtko

For those curious, here is the script. I apologize for Croatian
comments and literals and missing private libraries, but I think the
code is self-explanatory.
______________

# -*- coding: windows-1250 -*-

from os.path import getmtime, join
from os import walk, rename
from zipfile import ZipFile, ZIP_DEFLATED
from sets import Set
from StringIO import StringIO
from ftplib import FTP
from qvx.io import adapt_stdout, unadapt_stdout
from qvx.composite import Dot
from qvx.compositeut il import read_composite
import sys
import time

class DeploymentError (Exception):
pass

class Deployer:
def __init__ (self, cfg_file):
self.reset(cfg_ file)

def reset (self, cfg_file):
self.read_cfg(c fg_file)
self.local_file s = []
self.remote_fil es = []
self.new_files = []
self.deleted_fi les = []
self.newer_file s = []
self.older_file s = []
self.www_all_ti me = None
self.old_deploy ed = False

def read_cfg (self, cfg_file):
tree = read_composite( cfg_file)
self.cfg = Dot(tree).DEPLO YMENT

def prepare_file_li sts (self):
# Sastavi popis _datoteka_ u DIR direktoriju.
# Izostavi datoteke iz _notes direktorija
self.local_file s = []
for root, dirs, files in walk(self.cfg.D IR):
filtered = [join(root, f).replace('\\' , '/') for f in
files if f not in self.cfg.SKIP_F ILES]
self.local_file s.extend(filter ed)
for skip_dir in self.cfg.SKIP_D IRS.split(','):
if skip_dir.strip( ) in dirs:
dirs.remove(ski p_dir)

# Sastavi popis datoteka na serveru
# Koristi se sa informacijama od zadnjeg deploymenta
# Popis se nalazi u www_all.txt datoteci
self.remote_fil es = []
remote_stamps = {}
zip = ZipFile(self.cf g.FILE, 'r')
for line in zip.read('www_a ll.txt').split( '\n'):
name, stamp = line.split('\t' )
remote_stamps[name] = int(stamp)
self.remote_fil es.append(name)
self.www_all_ti me = zip.getinfo('ww w_all.txt').dat e_time

# Deployment nije obavljen ako nije zapisan log
self.old_deploy ed = 'deployment.log ' in zip.namelist()
zip.close()

# Rastavi datoteke u tri kategorije: nove, obrisane i iste
lset = Set(self.local_ files)
rset = Set(self.remote _files)
self.new_files = list(lset - rset)
self.deleted_fi les = list(rset - lset)
common_files = list(lset & rset)

# Pogledaj što se promijenilo u zajedničkim datotekama
self.newer_file s = []
self.older_file s = []
for name in common_files:
remotetime = remote_stamps[name]
localtime = getmtime(name) #+ 3600
# Ako je razlika unutar sekunde, zanemari
if abs(remotetime-localtime) > int(self.cfg.IG NORE_SEC):
if remotetime > localtime:
self.older_file s.append(name)
elif localtime > remotetime:
self.newer_file s.append(name)

def need_redeployme nt (self):
return not self.old_deploy ed

def check_changes (self):
# Ne bi trebalo biti starijih
if self.older_file s:
raise DeploymentError ('Ne smije biti starijih datoteka!')
if not (self.new_files or self.deleted_fi les or
self.newer_file s):
raise DeploymentError ('Nema promjena!')

def make_deployment _file (self):
# Uključi potrebne datoteke
deployment = ZipFile('new_'+ self.cfg.FILE, 'w', ZIP_DEFLATED)
for name in self.new_files + self.newer_file s:
deployment.writ e(name)

# Uključi popis svih datoteka
all_files = '\n'.join([f+'\t'+str(getm time(f)) for f in
self.local_file s])
deployment.writ estr('www_all.t xt', all_files)

# Uključi popis datoteka za obrisati
for_delete = '\n'.join(self. deleted_files)
if for_delete:
deployment.writ estr('www_delet e.txt', for_delete)
deployment.clos e()
print '\nNapravljena je nova deployment datoteka.'

# Preimenuj deployment datoteke
timestr = '%04d-%02d-%02d_%02d-%02d-%02d' % self.www_all_ti me
old_deployment = self.cfg.FILE.r eplace('.zip',
'_'+timestr+'.z ip')
rename(self.cfg .FILE, old_deployment)
rename('new_'+s elf.cfg.FILE, self.cfg.FILE)
print 'Stara deployment datoteka se sada zove', old_deployment

def exec_ftp (self, silent, logtext, func, *arg):
try:
self.ftp_log = self.ftp_log + '\n\n' + logtext
self.ftp_log = self.ftp_log + '\n' + func(*arg)
return 'OK'
except Exception, e:
self.ftp_log = self.ftp_log + '\n' + str(e)
if not silent:
raise DeploymentError (str(e))
return 'ERROR'

def deploy_ftp (self):
self.ftp_log = ''

# Spoji se na FTP server
print '\nSpajam se na ftp server %s ...' % (self.cfg.SERVE R,),
try:
ftp = FTP(self.cfg.SE RVER)
print 'OK'
except Exception, e:
print 'ERROR'
raise DeploymentError ('Ne mogu se spojiti na FTP server:
'+str(e))

# Logiraj se
print 'Logiram se kao %s ... ' % (self.cfg.USER, ),
print self.exec_ftp(F alse, 'LOGIN', ftp.login, self.cfg.USER,
self.cfg.PASSWO RD)

# Kopiraj datoteke
deployment = ZipFile(self.cf g.FILE, 'r')
deployment_file s = [n for n in deployment.name list() if n not
in ['www_all.txt', 'www_delete.txt ', 'deployment.log ']]
if deployment_file s:
print 'Šaljem datoteke:'
for name in deployment_file s:
bytes = deployment.read (name)
fp = StringIO(bytes)
print ' ', name, len(bytes), ' bytes ...',
print self.exec_ftp(T rue, 'STORBIN '+name, ftp.storbinary,
'STOR '+name, fp)
fp.close()

# Obriši datoteke
if 'www_delete.txt ' in deployment.name list():
deleted_files =
deployment.read ('www_delete.tx t').split('\n')
print 'Brišem datoteke:'
for name in deleted_files:
print ' ', name, '...',
print self.exec_ftp(T rue, 'DEL '+name, ftp.delete,
name)
deployment.clos e()

# Bye bye
print 'Završavam s radom ...',
print self.exec_ftp(T rue, 'BYE', ftp.quit)

# Ispiši FTP log
print '\nFTP log:'
print '-'*20,
print self.ftp_log

def write_log (self, text):
# Zapiši deployment log
deployment = ZipFile(self.cf g.FILE, 'a', ZIP_DEFLATED)
deployment.writ estr('deploymen t.log', text)
deployment.clos e()

def run_interactive ly (self):
# Adaptiraj stdout: mijenja kodnu stranicu u cp852 radi ispisa
# hrvatskih grafema, također logira sve poruke
ofa = adapt_stdout('c p852', True)

try:
try:
# Analiziraj datoteke
self.prepare_fi le_lists()
print '*'*5, 'Obrisani', '*'*5, self.deleted_fi les
print '*'*5, 'Novi ', '*'*5, self.new_files
print '*'*5, 'Noviji ', '*'*5, self.newer_file s
print '*'*5, 'Stariji ', '*'*5, self.older_file s

if self.need_redep loyment():
# Pitaj korisnika da li želi poslati od prije
pripremljeni deployment na server
yn = raw_input('\nOd prije pripremljeni deployment
nije obavljen.\n>>> Da li želite taj deployment poslati na server?
[y/N]: ')
if yn.lower().stri p() == 'y':
self.deploy_ftp ()
self.write_log( ''.join(ofa._lo g))
else:
self.check_chan ges()

# Pitaj korisnika da li želi napraviti deployment
datoteku
yn = raw_input('\n>> > Da li želite pripremiti
deployment? [y/N]: ')
if yn.lower().stri p() == 'y':
desc = raw_input('\n>> > Upišite kratki opis:
')
print '\nOpis:', desc

self.make_deplo yment_file()

# Pitaj korisnika da li želi poslati
deployment na server
yn = raw_input('\n>> > Da li želite poslati
deployment na server? [y/N]: ')
if yn.lower().stri p() == 'y':
self.deploy_ftp ()
self.write_log( ''.join(ofa._lo g))
except DeploymentError , e:
print str(e)
finally:
# Vrati stari stdout
unadapt_stdout( ofa)

if __name__ == '__main__':
deployer = Deployer('hpk.i ni')
deployer.run_in teractively()
x = raw_input('\n[Pritisnite Enter ...] ')
sys.exit(0)
Jul 18 '05 #1
3 1580
Qvx wrote:
Hello,

I'we written a simple web deployment program which scans for the
changes made to local copy of web site. Changed files are than
packaged into a zip file and deployed to web server.

Now here's the catch. Changes are computed using (1) log file from the
last deployment and (2) local file system. Log file contains
datestamps (integers) returned from os.path.getmtim e(f) function at
the time of last deployment. So i'm comparing two getmtime() values.
The problem is when Daylight saving kicks in: suddenly all local files
are reported as older than they were at the time of deployment.

How do I compensate for this?

Thanks,
Tvrtko


Never use the local time, always use GMT ( UTC ) time instead.

Since it seems os.path.getmtim e already gives UTC time, onemust wonder if
your OS isn't broken in some way ;) If you can't solve that problem, then
use a simple md5sum of the files instead. md5sum isn't that slow to compute
and it gives better results than timestanps.

Or use a specialised tool like rsync which does a very good job for that.

Jul 18 '05 #2
on my windows xp box os.path.getmtim e gives back local time (I just
saved the file):
os.path.getmtim e('c:\\temp\\te stset.py') 1106955016 print time.mktime(tim e.localtime()) 1106955034.0

You can try to figure out if DST is on by comparing time.localtime( )
versus time.gmtime(). In the Western European Timezone there's one hour
difference in winter and two hours in summer.
os.path.getmtim e('c:\\temp\\te stset.py') 1106954702 g = time.mktime(tim e.gmtime())
l = time.mktime(tim e.localtime())
print g, l 1106951381.0 1106954987.0 os.path.getmtim e('c:\\temp\\te stset.py') 1106955016 print time.mktime(tim e.localtime()) 1106955034.0 print l - g 3606.0


Jul 18 '05 #3
wi******@hotmai l.com wrote:
on my windows xp box os.path.getmtim e gives back local time (I just
saved the file):
os.path.get mtime('c:\\temp \\testset.py')
1106955016
print time.mktime(tim e.localtime())

1106955034.0


No. mktime is converting the local time to UTC. Try this instead:

Py> time.gmtime(os. path.getmtime(" c:/devel/mtime_test.txt" ))
(2005, 1, 29, 3, 35, 37, 5, 29, 0)

Py> time.localtime( os.path.getmtim e("c:/devel/mtime_test.txt" ))
(2005, 1, 29, 15, 35, 37, 5, 29, 1)

(This is with my machine set to Sydney time, so that I'm at UTC + 10, with
daylight savings currently active)
You can try to figure out if DST is on by comparing time.localtime( )
versus time.gmtime(). In the Western European Timezone there's one hour
difference in winter and two hours in summer.


To figure out if DST is currently active, you can use:

Py> import time
Py> time.localtime( )
(2005, 1, 29, 14, 29, 26, 5, 29, 0)
Py> time.localtime( ).tm_isdst
0

Switching to Sydney time (which actually uses DST, unlike Brisbane) gives:

Py> import time
Py> time.localtime( ).tm_isdst
1

The same trick will work on historical dates, too. For instance, consider a file
created last winter, when Sydney was NOT on daylight savings:

Py> time.localtime( os.path.getmtim e("c:/log.txt"))
(2004, 7, 20, 19, 46, 35, 1, 202, 0)

Cheers,
Nick.

--
Nick Coghlan | nc******@email. com | Brisbane, Australia
---------------------------------------------------------------
http://boredomandlaziness.skystorm.net
Jul 18 '05 #4

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

3
3666
by: Bathroom_Monkey | last post by:
For posterity's sake, here is an algorithm I created to take a GMT time and convert it to U.S. central time, accounting for daylight saving time. Note: this algorithm can be modified to work for any other U.S. timezone by changing the number of second subtracted at the end. <? $in_dst="false";
2
7214
by: hourang | last post by:
ok im getting tired of looking for an answer and coming up short with scripts that dont work. i have a application that uses GMT for all its times and needs the clients timeoffset for showing the correct times for everything. i use date.getTimezoneOffset() which works fine and shows the daylight savings time correct value of -4 since im in eastern standard time and its daylight savings time right now. well eastern standard time is...
1
7846
by: Ernie | last post by:
I am creating an .ics file that when opened (via Outlook) inserts a meeting into the calendar. All works fine unless the date and time I'm inserting happens to occur on the hour the time changes due to daylight savings. For example in 2004 the hours changed at 2:00 AM on April 4th (the first Sunday of April). Only on this day, if the start hour is 2 (2:00 AM, 2:15 AM, 2:45 AM), then an extra hour gets added so that 2:00 AM becomes...
10
5261
by: Marc Pelletier | last post by:
Hello, I am writing an application that does some simple astronomical calculations. One of the variables I need is the number of hours passed in this year. I've written the following function public static double GetHoursofYear( DateTime aTime ) { DateTime StartYear = new DateTime( aTime.Year, 1, 1 ); return ( aTime.ToOADate() - StartYear.ToOADate() ) * 24;
3
3255
by: chrisdevey | last post by:
Is there any way to make a System.Timers.Timer adjust for daylight savings time change? In a long running process I set a timer as follows for a daily expiration: _myTimer = new Timer(_myTimerDelegate, null, nextExpiration, TimeSpan.FromDays(1)); When we make the change out of daylight time back to standard time, the timer appears to fire one hour early (e.g., 4pm instead of 5pm). Is there a way to set this timer so that it is...
3
4325
by: mmuras | last post by:
I did not see any discussions / threads for this but if there is one please let me know: -First, I am one of only two individuals within my company's IT Dept. -We have a Windows Server 2003 R2 Standard Ed. Box for our Domain controller. -We are having issues STILL today in April with the Microsoft Windows Daylight Savings Issues ***Symptoms:
4
4402
by: Polaris431 | last post by:
I have a web application in ASP.NET that will be used globally. Data is collected on mobile devices running Windows Mobile and sent to the web server where it is stored and can be viewed. Data is timestamped when it is sent from a PDA device to the server. I am writing software for both the web app and the PDA. The web server is located at one location while the PDA devices are located around the world. The question is, how do I handle...
3
482
by: Generic Usenet Account | last post by:
Hi, Is there any way to make time-of-day adjustments for daylight savings using only standard time functions? We have a program that executes daily at a fixed time of day. After daylight savings happens, the time-of-day alignment is lost. For example, if the daily task gets kicked in at 9 p.m. every evening, after daylight savings ends in fall, the task is shown as kicking in at 8 p.m. Similarly, if the daily task gets kicked in at...
27
6883
by: RobG | last post by:
I was investigating a function to determine whether daylight saving was being observed on a particular date (given the platform's regional settings) and came across a suggestion at merlyn.com to test the time zone offset on a variety of dates to see if it changes. Based on that, I developed the following checkDST() function which, as far as I can tell, should be sufficient. It checks either the date passed to it or the current date with...
0
8730
by: Hystou | last post by:
Most computers default to English, but sometimes we require a different language, especially when relocating. Forgot to request a specific language before your computer shipped? No problem! You can effortlessly switch the default language on Windows 10 without reinstalling. I'll walk you through it. First, let's disable language synchronization. With a Microsoft account, language settings sync across devices. To prevent any complications,...
0
9367
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers, it seems that the internal comparison operator "<=>" tries to promote arguments from unsigned to signed. This is as boiled down as I can make it. Here is my compilation command: g++-12 -std=c++20 -Wnarrowing bit_field.cpp Here is the code in...
0
9215
jinu1996
by: jinu1996 | last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven tapestry of website design and digital marketing. It's not merely about having a website; it's about crafting an immersive digital experience that captivates audiences and drives business growth. The Art of Business Website Design Your website is...
0
9064
tracyyun
by: tracyyun | last post by:
Dear forum friends, With the development of smart home technology, a variety of wireless communication protocols have appeared on the market, such as Zigbee, Z-Wave, Wi-Fi, Bluetooth, etc. Each protocol has its own unique characteristics and advantages, but as a user who is planning to build a smart home system, I am a bit confused by the choice of these technologies. I'm particularly interested in Zigbee because I've heard it does some...
1
6669
isladogs
by: isladogs | last post by:
The next Access Europe User Group meeting will be on Wednesday 1 May 2024 starting at 18:00 UK time (6PM UTC+1) and finishing by 19:30 (7.30PM). In this session, we are pleased to welcome a new presenter, Adolph Dupré who will be discussing some powerful techniques for using class modules. He will explain when you may want to use classes instead of User Defined Types (UDT). For example, to manage the data in unbound forms. Adolph will...
0
4484
by: TSSRALBI | last post by:
Hello I'm a network technician in training and I need your help. I am currently learning how to create and manage the different types of VPNs and I have a question about LAN-to-LAN VPNs. The last exercise I practiced was to create a LAN-to-LAN VPN between two Pfsense firewalls, by using IPSEC protocols. I succeeded, with both firewalls in the same network. But I'm wondering if it's possible to do the same thing, with 2 Pfsense firewalls...
0
4753
by: adsilva | last post by:
A Windows Forms form does not have the event Unload, like VB6. What one acts like?
1
3189
by: 6302768590 | last post by:
Hai team i want code for transfer the data from one system to another through IP address by using C# our system has to for every 5mins then we have to update the data what the data is updated we have to send another system
2
2576
muto222
by: muto222 | last post by:
How can i add a mobile payment intergratation into php mysql website.

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.