This software gets the date from a naval time server and updates the system clock for posix OS supporting the "date" command. It also requires an internet connection.
WARNING: It will not work if your system clock is already off by more than 1 month.
TIP: Use kcron to schedule this script on a periodic basis.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 | #!/usr/bin/python
#
# File: nts_sync.py
# Author: Jason Letbetter
# Date: 8/24/2006
#
# This software gets the date from a naval time server and updates the system
# clock for posix OS supporting the "date" command. It also requires an
# internet connection.
#
# WARNING: It will not work if your system clock is already off by more than
# 1 month.
#
# TIP: Use kcron to schedule this script on a periodic basis.
#
# Example:
# jason@gummybear:~$ nts_sync.py
# Before update: Sat Aug 26 08:48:41 CDT 2006
# Updating to: Sat Aug 26 13:48:41 UTC 2006
# After update: Sat Aug 26 08:48:41 CDT 2006
#
import sys, os, re, urllib2
def main(argv):
# Print current date
sys.stdout.write('Before update: ')
sys.stdout.flush()
os.system('date')
# Update date from naval server
date = GetDate()
sys.stdout.write('Updating to: ')
sys.stdout.flush()
os.system('sudo date -u %s' % date)
# Print updated date
sys.stdout.write('After update: ')
sys.stdout.flush()
os.system('date')
def GetLocalYear(svrMo):
# Use the local machine's year b/c naval server doesn't have it
i,o = os.popen4('date')
date = o.read()
yr = int(date[-5:-1],10)
# TRICKY: We have to be careful around January 1st
svrMo = int(svrMo)
locMo = int(monthMap[date[4:7]])
# Assume local machine is slow and its near Jan 1st
if svrMo == 1 and locMo == 12:
yr+=1
# Assume local machine is fast and its near Jan 1st
elif svrMo == 12 and locMo == 1:
yr-=1
return str(yr)
def GetDate():
# Read date from naval time server (tax payers only ;^)
url = urllib2.urlopen('http://tycho.usno.navy.mil/cgi-bin/timer.pl')
text = url.read()
# Parse text to get UTC date strings
regx = r'([a-z,A-Z,]+)\.\s+(\d+)\,\s+(\d+):(\d+):(\d+)\s+UTC'
mo, da, hr, mi, se = re.search(regx, text).groups()
# Compute month number from abbreviation
mo = monthMap[mo]
# Get the year from our local clock
yr = GetLocalYear(mo)
# Return the proper date format
return mo+da+hr+mi+yr+'.'+se
monthMap = {
'Jan': '01', 'Feb': '02', 'Mar': '03', 'Apr': '04',
'May': '05', 'Jun': '06', 'Jul': '07', 'Aug': '08',
'Sep': '09', 'Oct': '10', 'Nov': '11', 'Dec': '12'
}
if __name__ == '__main__':
main(sys.argv[1:])
|
I wrote this b/c I have a mythtv server w/ a bad clock that slowly gains time. This was causing me to miss the end of my recorded broadcasts.
I scheduled this script to run every night (using kcron). Its difficult to quantify what the worst case error is, but it seems to fix my problem.
I wanted a time server that supported seconds and maintains a consistent output format. After briefly searching for time servers, I chose the naval time server.
The problem w/ the naval time server is that it doesn't show the year. So I get the year from the local clock. This gets tricky around December 31st at midnight. The code deals with the problem by assuming your local clock is no more than 1 month off.
If you know a time server that supports seconds and year feel free to modify the script and post your patch.