44

I have a date time of my django object but it can be any time of the day. It can be at any time through the day, but I need to set my time to 00:00:00 (and another date to 23:59:59 but the principle will be the same)

end_date = lastItem.pub_date

currently the end date is 2002-01-11 12:34:56 What do I need to do to get this to change it to 00:00:00?

i tried:

end_date.hour = '00'

but got: 'datetime.datetime' object attribute 'time' is read-only

Deduplicator
  • 44,692
  • 7
  • 66
  • 118
Designer023
  • 1,902
  • 1
  • 26
  • 43

5 Answers5

63

Using datetimes's "combine" with the time.min and time.max will give both of your datetimes. For example:

from datetime import date, datetime, time
pub_date = date.today()
min_pub_date_time = datetime.combine(pub_date, time.min) 
max_pub_date_time = datetime.combine(pub_date, time.max)  

Result with pub_date of 6/5/2013:

min_pub_date_time -> datetime.datetime(2013, 6, 5, 0, 0)

max_pub_date_time -> datetime.datetime(2013, 6, 5, 23, 59, 59, 999999)

raman
  • 711
  • 5
  • 6
57

Try this:

import datetime
pub = lastItem.pub_date
end_date = datetime.datetime(pub.year, pub.month, pub.day)
mipadi
  • 398,885
  • 90
  • 523
  • 479
  • 72
    An alternative would be `end_date.replace(hour=0, minute=0, second=0)`. – Andrew Clark Dec 02 '11 at 19:32
  • 14
    To ensure it's totally zeroed out, you may need to add microsecond=0 to F.J's suggestion. For instance, when you're zeroing out the time portion of datetime.now(). – Adam Hollidge Aug 21 '12 at 20:19
  • @F.J Are you sure? I get "'second' is an invalid keyword argument for this function" (or 'hour', or 'minute') when I do that. And it's a datetime object not a date. Maybe I was doing something wrong tho. – R Thiede Oct 04 '12 at 10:08
  • 1
    @RThiede [`datetime.datetime.replace()`](http://docs.python.org/library/datetime.html#datetime.datetime.replace) is working fine for me with `second` and `microsecond` keyword arguments, make sure that you have a `datetime.datetime` instance and not a `datetime.date`. – Andrew Clark Oct 04 '12 at 16:25
  • 2
    @AndrewClark: 1. you forgot `microsecond` in your first comment. 2. `.replace()` may return an unnormalized value for an aware datetime object that may introduce ~1h error around DST transitions. Both `.combine()` and `datetime()` methods strip the timezone info so that you can [add the correct value instead of using by accident a possibly incorrect value returned by `.replace()`](http://stackoverflow.com/a/11236372/4279) – jfs Jun 30 '15 at 12:18
  • @AndrewClark - this should be an individual answer, adding the microsecond part as said by anh – Snigdha Batra Dec 10 '15 at 10:58
23

Are you sure you don't want to use dates instead of datetimes? If you're always setting the time to midnight, you should consider using a date. If you really want to use datetimes, here's a function to get the same day at midnight:

def set_to_midnight(dt):
    midnight = datetime.time(0)
    return datetime.datetime.combine(dt.date(), midnight)
Gavin Wahl
  • 1,193
  • 8
  • 21
11

For tz-aware dates it should be:

datetime.combine(dt.date(), datetime.min.time(), dt.tzinfo)
Antony Hatchkins
  • 31,947
  • 10
  • 111
  • 111
1

datetime instance attributes like year, month, day, hour, etc are read-only, so you just have to create a new datetime object and assign it to end_date.

jan zegan
  • 1,629
  • 1
  • 12
  • 18