Skip to content

Instantly share code, notes, and snippets.

@temoto
Created November 1, 2011 11:46
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save temoto/1330373 to your computer and use it in GitHub Desktop.
Save temoto/1330373 to your computer and use it in GitHub Desktop.
Python time machine contextmanager for tests
# Except it would not work, because TypeError: can't set attributes of built-in/extension type 'datetime.datetime'
@contextmanager
def time_machine(now=None, utcnow=None, today=None):
if now is None and utcnow is None and today is None:
raise ValueError(u"At least one of `now`, `utcnow` or `today` must be specified.")
real_now = datetime.now()
real_utcnow = datetime.utcnow()
tz_delta = real_now - real_utcnow
if now is None and today is not None:
now = real_now.replace(year=today.year, month=today.month, day=today.day)
utcnow = now - tz_delta
if utcnow is None and today is not None:
utcnow = real_utcnow.replace(year=today.year, month=today.month, day=today.day)
now = utcnow + tz_delta
if today is None:
today = now.date()
mock_now, mock_utcnow, mock_today = lambda: now, lambda: utcnow, lambda: today
(save_now, save_utcnow, save_today, datetime.now, datetime.utcnow, date.today) = (
datetime.now, datetime.utcnow, date.today, mock_now, mock_utcnow, mock_today)
yield
datetime.now, datetime.utcnow, date.today = save_now, save_utcnow, save_today
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment