Skip to content

Instantly share code, notes, and snippets.

@nihal111
Last active May 4, 2024 19:00
Show Gist options
  • Save nihal111/23faa51c3f88a281b676dcbac77ce015 to your computer and use it in GitHub Desktop.
Save nihal111/23faa51c3f88a281b676dcbac77ce015 to your computer and use it in GitHub Desktop.
A python script to update system time in Windows by attempting to fetch time from multiple NTP servers from a defined list.
import socket
import struct
import sys
import time
import datetime
import win32api
# List of servers in order of attempt of fetching
server_list = ['ntp.iitb.ac.in', 'time.nist.gov', 'time.windows.com', 'pool.ntp.org']
'''
Returns the epoch time fetched from the NTP server passed as argument.
Returns none if the request is timed out (5 seconds).
'''
def gettime_ntp(addr='time.nist.gov'):
# http://code.activestate.com/recipes/117211-simple-very-sntp-client/
TIME1970 = 2208988800 # Thanks to F.Lundh
client = socket.socket( socket.AF_INET, socket.SOCK_DGRAM )
data = '\x1b' + 47 * '\0'
try:
# Timing out the connection after 5 seconds, if no response received
client.settimeout(5.0)
client.sendto( data, (addr, 123))
data, address = client.recvfrom( 1024 )
if data:
epoch_time = struct.unpack( '!12I', data )[10]
epoch_time -= TIME1970
return epoch_time
except socket.timeout:
return None
if __name__ == "__main__":
# Iterates over every server in the list until it finds time from any one.
for server in server_list:
epoch_time = gettime_ntp(server)
if epoch_time is not None:
# SetSystemTime takes time as argument in UTC time. UTC time is obtained using utcfromtimestamp()
utcTime = datetime.datetime.utcfromtimestamp(epoch_time)
win32api.SetSystemTime(utcTime.year, utcTime.month, utcTime.weekday(), utcTime.day, utcTime.hour, utcTime.minute, utcTime.second, 0)
# Local time is obtained using fromtimestamp()
localTime = datetime.datetime.fromtimestamp(epoch_time)
print("Time updated to: " + localTime.strftime("%Y-%m-%d %H:%M") + " from " + server)
break
else:
print("Could not find time from " + server)
@thomas-vincent
Copy link

The only windows specific function is win32.SetSystemTime
You can replace as in https://stackoverflow.com/questions/12081310/python-module-to-change-system-date-and-time#12292874

@DrPaprikaa
Copy link

win32api.SetSystemTime() requires admin privileges, is there a workaround ?
I've seen this SO answer but it's not what I' looking for. My code runs 24/7 and I need to update the clock regularly : ideally I would like this method only to have admin privileges, not the whole script

@uniextra
Copy link

Getting this error.
Traceback (most recent call last):
File "ntp_update_time.py", line 35, in
epoch_time = gettime_ntp(server)
File "ntp_update_time.py", line 23, in gettime_ntp
client.sendto( data, (addr, 123))
TypeError: a bytes-like object is required, not 'str'

@mahakg290399
Copy link

Getting this error.
Traceback (most recent call last):
File "ntp_update_time.py", line 35, in
epoch_time = gettime_ntp(server)
File "ntp_update_time.py", line 23, in gettime_ntp
client.sendto( data, (addr, 123))
TypeError: a bytes-like object is required, not 'str'

I am also getting the same error.

@erwanito12
Copy link

erwanito12 commented Dec 1, 2021

we must add this except line 31:

except socket.gaierror:
return None

to correct this error :

Getting this error.
Traceback (most recent call last):
File "ntp_update_time.py", line 35, in
epoch_time = gettime_ntp(server)
File "ntp_update_time.py", line 23, in gettime_ntp
client.sendto( data, (addr, 123))
TypeError: a bytes-like object is required, not 'str'

@holahapi
Copy link

it works for my script(utf-8) by replace line 19 with
data = bytes('\x1b' + 47 * '\0','utf-8')

you also need to run as admin to change the time,

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment