Python module to change system date and time

How can I change System Date, Time, Timezone in Python? Is there any module available for this?

  1. I don’t want to execute any system commands
  2. 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

0 0 votes
Article Rating
Subscribe
Notify of
guest

0 Comments
Oldest
Newest Most Voted
Inline Feedbacks
View all comments
0
Would love your thoughts, please comment.x
()
x