0

How do I print the time every 10 seconds based off of using the % operator and the datetime package? This only prints once...

from datetime import datetime, timezone, timedelta
import time

now_utc = datetime.now(timezone.utc)

while True:
    if (now_utc - datetime.now(timezone.utc)).total_seconds() % 10 == 0:
        print(time.ctime())
S. C.
  • 110
  • 1
  • 13
bbartling
  • 3,288
  • 9
  • 43
  • 88
  • 1
    This does expect a floating-point value to precisely equal 0.0. This loop also spins really aggressively, completely consuming the thread. – tadman Dec 30 '22 at 18:25
  • Indeed: 1st `round` your delta, then implement a way to print the date only once every 10 secs. – Swifty Dec 30 '22 at 18:27
  • What's the maximum tolerable error for reporting time here? – Michael Ruth Dec 30 '22 at 18:28
  • 1
    Works on my machine. Only removed timedelta as an unnecessary dependency. – enslaved_programmer Dec 30 '22 at 18:28
  • @tadman what would be a better approach for not spinning aggressively consuming the entire thread? Ideally im just curious to compare a time stamp and if its greater than 10 seconds from the previous time stamp...print the time – bbartling Dec 30 '22 at 18:31
  • 2
    Depends on how accurate you want the timing. There are async options for Python with more fine-grained timing methods, and recurring timers. – tadman Dec 30 '22 at 18:56

1 Answers1

1

In response to comments on the question: you can do this without datetime and %. The benefit is that it's much simpler.

import time

POLLING_PERIOD = 0.1 #  seconds


if __name__ == '__main__':
    prev_time = time.time()
    print(time.ctime())
    while True:
        cur_time = time.time()
        if cur_time - prev_time >= 10:
            prev_time = cur_time
            print(time.ctime())
        time.sleep(POLLING_PERIOD)

This script gets the seconds from Unix epoch and prints the current time every 10s. You can adjust the polling period to minimize spinning and ensure that the time is printed only every 10s, rather than 11s, 12s, etc. due to poor resolution.

Please note that this script is susceptible to drift due to inaccuracy of time.sleep() and will eventually print a time which is greater than 10s since the last printed time.


After running some experiments on a system with low load, time.sleep() performs very well over several hours if the sleep time is adjusted based on the difference between the previous and current times.

import time

REPORTING_INTERVAL = 10  # seconds


if __name__ == '__main__':
    prev_time = time.time()
    sleep_time_adj = 0
    print(time.ctime())
    while True:
        time.sleep(REPORTING_INTERVAL - sleep_time_adj)
        print(time.ctime())
        cur_time = time.time()
        sleep_time_adj = cur_time - prev_time - REPORTING_INTERVAL
        prev_time = cur_time

It really comes down to how accurate this needs to be, how long it's going to run, and the system it will run on.

Michael Ruth
  • 2,938
  • 1
  • 20
  • 27