How can I change System Date, Time, Timezone in Python? Is there any module available for this?
- I don’t want to execute any system commands
- I want one common solution, which should work on both Unix and Windows.
Answers:
Thank you for visiting the Q&A section on Magenaut. Please note that all the answers may not help you solve the issue immediately. So please treat them as advisements. If you found the post helpful (or not), leave a comment & I’ll get back to you as soon as possible.
Method 1
import sys
import datetime
time_tuple = ( 2012, # Year
9, # Month
6, # Day
0, # Hour
38, # Minute
0, # Second
0, # Millisecond
)
def _win_set_time(time_tuple):
import pywin32
# http://timgolden.me.uk/pywin32-docs/win32api__SetSystemTime_meth.html
# pywin32.SetSystemTime(year, month , dayOfWeek , day , hour , minute , second , millseconds )
dayOfWeek = datetime.datetime(time_tuple).isocalendar()[2]
pywin32.SetSystemTime( time_tuple[:2] + (dayOfWeek,) + time_tuple[2:])
def _linux_set_time(time_tuple):
import ctypes
import ctypes.util
import time
# /usr/include/linux/time.h:
#
# define CLOCK_REALTIME 0
CLOCK_REALTIME = 0
# /usr/include/time.h
#
# struct timespec
# {
# __time_t tv_sec; /* Seconds. */
# long int tv_nsec; /* Nanoseconds. */
# };
class timespec(ctypes.Structure):
_fields_ = [("tv_sec", ctypes.c_long),
("tv_nsec", ctypes.c_long)]
librt = ctypes.CDLL(ctypes.util.find_library("rt"))
ts = timespec()
ts.tv_sec = int( time.mktime( datetime.datetime( *time_tuple[:6]).timetuple() ) )
ts.tv_nsec = time_tuple[6] * 1000000 # Millisecond to nanosecond
# http://linux.die.net/man/3/clock_settime
librt.clock_settime(CLOCK_REALTIME, ctypes.byref(ts))
if sys.platform=='linux2':
_linux_set_time(time_tuple)
elif sys.platform=='win32':
_win_set_time(time_tuple)
I don’t have a windows machine so I didn’t test it on windows… But you get the idea.
Method 2
The tMC’s answer seems great. However, it was not working for me properly. I figured out it needed some updates, for both Linux and Windows + python 3. Here is my updated module:
import sys
from _datetime import datetime
time_tuple = (2012, # Year
9, # Month
6, # Day
0, # Hour
38, # Minute
0, # Second
0, # Millisecond
)
def _win_set_time(time_tuple):
import win32api
dayOfWeek = datetime(*time_tuple).isocalendar()[2]
t = time_tuple[:2] + (dayOfWeek,) + time_tuple[2:]
win32api.SetSystemTime(*t)
def _linux_set_time(time_tuple):
import subprocess
import shlex
time_string = datetime(*time_tuple).isoformat()
subprocess.call(shlex.split("timedatectl set-ntp false")) # May be necessary
subprocess.call(shlex.split("sudo date -s '%s'" % time_string))
subprocess.call(shlex.split("sudo hwclock -w"))
if sys.platform == 'linux2' or sys.platform == 'linux':
_linux_set_time(time_tuple)
elif sys.platform == 'win32':
_win_set_time(time_tuple)
For Linux read the following answer: Set the hardware clock in Python?
Method 3
I had to modify win32 version of tMC’s answer little bit:
def _win_set_time(time_tuple):
import win32api
dayOfWeek = datetime(*time_tuple).isocalendar()[2]
t = time_tuple[:2] + (dayOfWeek,) + time_tuple[2:]
win32api.SetSystemTime(*t)
Eg. when I use it to set time according to old time server (Time protocol, RFC868) I’m doing it aproximately this way:
data = s.recv(4) remote_time = (ord(data[0])<<24) + (ord(data[1])<<16) + (ord(data[2])<<8) + ord(data[3]) remote_time -= 2208988800 _win_set_time(time.gmtime(remote_time)[0:6] + (0,))
Method 4
This works for me
- Convert automatically to UTC Time
- convert string to datetime
- use date time input
- it is more readable
def _win_set_time(datetime_obj: datetime):
import win32api
# http://timgolden.me.uk/pywin32-docs/win32api__SetSystemTime_meth.html
# win32api.SetSystemTime(year, month , dayOfWeek , day , hour , minute , second , millisecond )
utc_datetime = datetime_obj.astimezone().astimezone(timezone.utc).replace(tzinfo=None)
day_of_week = utc_datetime.isocalendar()[2]
win32api.SetSystemTime(utc_datetime.year, utc_datetime.month, day_of_week,
utc_datetime.day, utc_datetime.hour, utc_datetime.minute, utc_datetime.second,
int(utc_datetime.microsecond / 1000))
real_time_str = "2020 12 24 13 11 10 321"
real_time = datetime.strptime(real_time_str, '%Y %m %d %H %M %S %f')
_win_set_time(real_time)
Method 5
well for now i think this is the best solution
import sys,os
def change(s):
if s == 1:os.system('date -s "2 OCT 2006 18:00:00"')#don't forget to change it , i've used date command for linux
elif s == 2:
try:
import pywin32
except ImportError:
print 'pywin32 module is missing'
sys.exit(1)
pywin32.SetSystemTime(year, month , dayOfWeek , day , hour , minute , second , millseconds )# fill all Parameters with int numbers
else:print 'wrong param'
def check_os():
if sys.platform=='linux2':change(1)
elif sys.platform=='win32':change(2)
else:print 'unknown system'
for now it’s temporary solution , hopefully it’s helpful , aslo take a look
http://timgolden.me.uk/pywin32-docs/win32api__SetSystemTime_meth.html
http://timgolden.me.uk/pywin32-docs/win32api__SetLocalTime_meth.html
All methods was sourced from stackoverflow.com or stackexchange.com, is licensed under cc by-sa 2.5, cc by-sa 3.0 and cc by-sa 4.0