Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to overwrite a datetime.now() object

Tags:

python

I am trying to implement a get_date function which I want to use to build higher-level functions (for example, get_payment_date given below). This is my code:

from datetime import datetime

def get_date(year=None, month=None, day=None):
    '''Returns now, with the given parts overwritten'''
    dt = datetime.now()
    if not year  is None : dt.year  = year
    if not month is None : dt.month = month
    if not day   is None : dt.day   = day
    return dt

def get_payment_date():
    return get_date(day=15)

print get_payment_date()

But if fails:

AttributeError: attribute 'day' of 'datetime.date' objects is not writable

I get it. How can I solve this? How can I "overwrite" only some parts of now?

like image 256
blueFast Avatar asked Oct 15 '13 08:10

blueFast


2 Answers

datetime.datetime and datetime.date objects are immutable.

You can do dt = dt.replace(year = year) to get a new datetime object based on an old one.

You don't necessarily want to do that three times, but something like this might suit you:

def get_date(**kwargs):
    '''Returns now, with the given parts overwritten'''
    dt = datetime.now()
    # optionally, depending on intended use of this function
    kwargs = { k : v for k,v in kwargs.items() if v is not None }
    return dt.replace(**kwargs)
like image 102
Steve Jessop Avatar answered Nov 08 '22 15:11

Steve Jessop


This is what I wanted (thanks to Steve Jessop):

from datetime import datetime

def get_date(year=None, month=None, day=None):
    '''Returns now, with the given parts overwritten'''
    dt = datetime.now()
    kwargs = {}
    if year  : kwargs['year']  = year
    if month : kwargs['month'] = month
    if day   : kwargs['day'] = day
    if kwargs : return dt.replace(**kwargs)
    else      : return dt

def get_payment_date():
    return get_date(day=15)

print get_payment_date()

Notice that I need to build a kwargs since dt.replace does not accept None as value for year / month / day. Also, I removed is not None check, since a 0 value means also no replacement.

like image 43
blueFast Avatar answered Nov 08 '22 17:11

blueFast