14

In Python 2.7.2 I am getting the seconds since epoch using:

sec_since_epoch = (date_obj - datetime(1970, 1, 1, 0, 0)).total_seconds()

Now I want to round these seconds to the nearest day e.g. if:

datetime.fromtimestamp(sec_since_epoch)

corresponds to datetime(2013, 12, 14, 5, 0, 0)

I want the new timestamp to correspond to datetime(2013, 12, 14, 0, 0, 0)

I know the ugly way of doing it, but is there an elegant way ?

Lyman Zerga
  • 1,415
  • 3
  • 19
  • 40

4 Answers4

31

You can use datetime.timetuple() to manipulate with the date. E.g. in this way:

from datetime import datetime


dt = datetime(2013, 12, 14, 5, 0, 0)
dt = datetime(*dt.timetuple()[:3]) # 2013-12-14 00:00:00
print dt.strftime('%s') # 1386997200

DEMO

Eugene Naydenov
  • 7,165
  • 2
  • 25
  • 43
  • 1
    This truncates the time rather than rounding it - i.e. 11pm will round down to the beginning of the day rather than rounding up to the next – bendl Jun 07 '23 at 14:23
10

Sure, just convert the datetime to a date first:

sec_since_epoch = (date_obj.date() - date(1970, 1, 1)).total_seconds()

Of course date() truncates. If you want to round up if on or after noon, etc., just add 12 hours before truncating, or check whether the date is >= noon on the same day and if so add a day (note that these can do different things on DST boundary days), or whatever rule you want to round by.

abarnert
  • 354,177
  • 51
  • 601
  • 671
  • If I do `ts = (datetime(2013, 10, 31, 5, 0).date() - date(1970, 1, 1)).total_seconds()` and then do `datetime.fromtimestamp(ts)`, I still get `datetime.datetime(2013, 10, 30, 17, 0)`, where the hours are not 0 – Lyman Zerga Nov 01 '13 at 00:04
  • 2
    @LymanZerga: The timestamp is for midnight 31 Oct 2013 GMT, which is apparently 17:00 30 Oct 2013 in your local timezone, which is what you're seeing. Read the docs on naive datetime objects. – abarnert Nov 01 '13 at 00:29
2

For modern Pandas versions ;), I would consider using the appropriate rounding functions. You have the selection of floor, round and ceil... e.g. for:

t_max_overall=pd.Timestamp('2022-05-05 10:03:33.086966+0000', tz='UTC')

then:

t_max_overall.floor('1d')

Returns:Timestamp('2022-05-05 00:00:00+0000', tz='UTC')

While:

t_max_overall.round('1d')

Returns Timestamp('2022-05-05 00:00:00+0000', tz='UTC'),

And:

t_max_overall.ceil('1d'))

Returns: Timestamp('2022-05-06 00:00:00+0000', tz='UTC')

ntg
  • 12,950
  • 7
  • 74
  • 95
1

Here's a pretty intuitive way, it may be a little barbaric looking but it works in one line.

Basically, the logic is get your current date, then subtract all the hours minutes, second and microseconds you have, and then add one day ( that's if you want to round up, otherwise just leave it if you're rounding down.)

   from datetime import date,timedelta

    Rounded_date =  ( the_date - timedelta(hours=date.hour, minutes=date.minute,
    seconds=date.second, microseconds=date.microsecond) ) + timedelta(days=1)
puistori
  • 76
  • 6