Gentoo Wiki ArchivesGentoo Wiki

HOWTO_Syncing_Time_via_internet


This article is part of the HOWTO series.
Installation Kernel & Hardware Networks Portage Software System X Server Gaming Non-x86 Emulators Misc

Contents

Introduction

You may want to periodically sync your system-clock with some external timeserver. If you want an accurate time, this howto will not serve you well. You should then rather read HOWTO NTP. This howto is mostly for people whose system clocks get out of sync very rapidly due to a dying CMOS-Battery etc. and who can live with an inaccuracy of up to two minutes (worst case). On this site you will learn how to use the www.worldtimeserver.com timeserver to set your system clock by utilizing the cron job manager and the provided python-script.

The script provided on this page was inspired by a python-script written by Matthias Luebben. The original script can be found here: http://ml81.dyndns.org/~tux/utctime.py His script is a little bit more complex but also allows you to define the format of the time that is returned by the script much in the same way that is possible with commands like date etc. It is however not possible to replace the script provided here with the original script and expect the proceeding instructions to work properly. The original script doesn't provide the appropriate formatting information, so I advise you to stick to the version of the script provided on this site unless you know what you are doing.

What you need

The script

Save the following script onto a directory that is contained in the $PATH variable of user root. /usr/sbin or even better /usr/local/sbin are both good locations for this purpose. Choose an appropriate name like ut.py (update time) or whatever makes sense to you. The following instructions assume that you have called the script ut.py and saved it into the /usr/local/sbin directory. Keep this in mind when you enter the absolute path to the script and modify it to suit the location where you put ut.py on your system. You can verify whether a directory is contained in $PATH by issuing echo $PATH.

localhost ~ # echo $PATH

Remember that the script must be executable. You achieve this by running following command

chmod a+x /usr/local/sbin/ut.py
File: /usr/local/sbin/ut.py
#!/usr/bin/python

##################################################################################
# Name:         ut.py (update time)
# Version:      0.4
# Purpose:      Extract UTC-time from http://www.worldtimeserver.com/
# Author:       Mehdi Salem Naraghi. (inspired by ucttime.py by M. Luebben.)
# Modified by:
# Created:      18.12.2005 (dd.mm.yyyy)
# Copyright:    Copyright (C) 2005-2006 M. Mehdi Salem Naraghi <momesana@yahoo.de>
# License:      Distributed under the terms of the GNU General Public License v2
###################################################################################

import urllib2, re, sys, time, string, os

# ======================= FUNCTIONS ========================

def getLocalTime():
	utc = time.gmtime()
	localTime = (hour, minute, day, month, year) = (str(utc[3]), str(utc[4]), str(utc[2]), str(utc[1]), str(utc[0]))
	return list(localTime)

#-------------------------------------------------------
def getServerTime():
	try:
		url = urllib2.urlopen( \
		"http://www.worldtimeserver.com/current_time_in_UTC.aspx")
		html = url.read()
	
	except:
		print "error: downloading date/time website " \
		"from www.worldtimeserver.com"
		sys.exit(1)
	
	mtbl = {"January"   :  '01', "February" :  '02',
		"March"     :  '03', "April"    :  '04',
		"May"       :  '05', "June"     :  '06',
		"July"      :  '07', "August"   :  '08',
		"September" :  '09', "October"  :  '10',
		"November"  :  '11', "December" :  '12'}
	
	patTime = r"""
		UTC/GMT\s+is\s+
		(?P<hour>\d+)		# hour
		:
		(?P<minute>\d+)		# minute
		\s+on\s+\S+,\s+
		(?P<month>[A-z]+)	# month
		\s+
		(?P<day>\d+)		# day
		,\s+
		(?P<year>\d+)		# year
		"""
	
	serverTime = [hour, minute, day, month, year] = \
		list(re.compile(patTime, re.VERBOSE).search(html).group('hour', 'minute', 'day', 'month', 'year'))
	
	serverTime[3] = mtbl[serverTime[3]]
	return serverTime

#-------------------------------------------------------
def needsUpdate(lt, st):
	#compare Date and hour
	if not ((int(lt[0]) == int(st[0])) and \
		(int(lt[2]) == int(st[2])) and \
		(int(lt[3]) == int(st[3])) and \
		(int(lt[4]) == int(st[4]))):
		return True
	#compare minute
	if (int(lt[1]) - int(st[1]) > 1) or (int(st[1]) - int(lt[1]) > 1):
		return True
	else:
		return False

#-------------------------------------------------------
def time2str(st):
	return st[3]+st[2]+st[0]+st[1]+st[4]

# ======================== MAIN =========================

serverTime = getServerTime()
getServerTime()

if needsUpdate(getLocalTime(), serverTime):
	print "performing update"
	os.system('date -u ' + time2str(serverTime))
else:
	print "skipping update"

Testing the script

Issue ut.py (or whatever you called the script) on the command line.

localhost ~ # ut.py
performing update
Mi Feb 22 21:57:00 CET 2006

If the system-clock is already accurate enough the output will be like this:

 localhost ~ # ut.py
skipping update

You could now update the time of your system clock by issuing following command (as root):

ut.py

or

/usr/local/sbin/ut.py

This would set the system's UTC (GMT) time to the value returned by ut.py. The utc time may differ from your local time and that's perfectly alright because your system calculates the local time by adding or subtracting an offset to/from the utc time. In Germany for example, setting the system clock to utc-time 21:48 results in the local time 22:48. The system takes care of that, so you don't need to worry about it. For UTC to work properly remember to set the /etc/localtime symlink to your location. The different location categories can be found under /usr/share/zoneinfo/. To set the local time to that of Germany (Europe > Berlin) you would do following:

localhost ~ # ln -sf /usr/share/zoneinfo/Europe/Berlin /etc/localtime

You can verify this with:

localhost ~ # ls -l /etc/localtime
lrwxrwxrwx  1 root root 33 Jan  1 06:32 /etc/localtime -> /usr/share/zoneinfo/Europe/Berlin

The script decently gets the job done but always having to run this command in order to update the time is pretty tiresome and annoying. It would be nice to automate this task so it is carried out by the system auto-magically. Cron enables us to do just this. Read on to find out how this can be done.

Setting up cron the CLI way

Since doing this requires a little bit of knowledge about cron I refer you to the cron man/info pages and following Gentoo howtos that give you a first insight into cron:

A very simple setup that would sync the clock once every hour would be achieved like this: First you have to create a cron-file (with .cron as suffix) and copy it into the corresponding cron directory. For a script that is executed once every hour you would copy the cron-file to /etc/cron.hourly/.

create a file with following content in /etc/cron.hourly:

File: /etc/cron.hourly/updatetime.cron
#! /bin/sh
python /usr/local/sbin/ut.py

make it executable with:

chmod a+x /etc/cron.hourly/updatetime.cron

In order to have more controll you will have to become more intimate with cron, in which case I suggest you to read the above mentioned cron resources and also google for more tutorials. I advise you to use kcron for this task though, at least when you are not a cron wizard. ;)

Setting up cron using Kcron

Start Kcron as user root and click on the (System Cron) entry in the displayed TreeView. The System Cron entry has probably two subentries:

What we are interested in is the Tasks entry. You need to rightclick it and select 'New'. This will create an new Task and pop up a dialog in which you can set its properties. following Entries need to be modified:

  1. Run as --> set this to root
  2. Program --> set this to: /usr/local/sbin/ut.py
  3. The "Enabled" Checkbox must be checked.
  4. The "Run every day" entry in the "Daily" groupbox must also be checked.
  5. In the "Hours" & "Minutes" groupboxes you can set the intervals you wish the program to be executed at.

Now click ok and save the changes with the 'Save' button in the toolbar or by selecting File > Save from the menubar. This is important since the changes are not set to effect before you save them. Check to see whether the Run as setting is set right. My Kcron wouldn't set it correctly unless I closed and relaunched kcron and edited those entries again.

Visual Guide for kcron setup

Troubleshooting

Traceback (most recent call last):
 File "/usr/local/bin/ut.py", line 82, in ?
   serverTime = getServerTime()
 File "/usr/local/bin/ut.py", line 56, in getServerTime
   serverTime = [hour, minute, day, month, year] = \
AttributeError: 'NoneType' object has no attribute 'group'

This was solved by a restructuring of the www.worldtimeserver.com page. The solution is to either change the url in the urlopen() function of the scribt to http://www.worldtimeserver.com/current_time_in_UTC.aspx instead of http://www.worldtimeserver.com or using the newest version of the script which already incorporates the fix. Thanx to proteus for reporting.

Here is an example:

Code: Output of tailf /var/log/everything/current
...
Dec 25 23:05:01 [cron] (root) CMD (/usr/sbin/ut.py)
...
Dec 25 23:10:01 [cron] (root) CMD (/usr/sbin/ut.py)
...

See also

Retrieved from "http://www.gentoo-wiki.info/HOWTO_Syncing_Time_via_internet"

Last modified: Thu, 04 Sep 2008 14:06:00 +1000 Hits: 23,459

Created by NickStallman.net, Luxury Homes Australia
Real estate agents should list their apartments, townhouses and units in Australia.