2
from datetime import datetime
roughtime = datetime(2018,1,1,5,2,1)

I want to floor roughtime as datetime.datetime(2018, 1, 1, 0, 0, 0) and also ceil roughtime as datetime.datetime(2018, 1, 2, 0, 0, 0).

Is there any convenient way to realize this? I know I can convert roughtime using matplotlib.dates.date2num. But I wonder if there are other ingenious ideas 

Tim Stack
  • 3,209
  • 3
  • 18
  • 39
AskNature
  • 85
  • 1
  • 7
  • related: https://stackoverflow.com/q/3463930/10197418 – FObersteiner Jul 24 '20 at 11:54
  • if you happen to work with `pandas`, you'd have `round`, `floor` and `ceil` methods which you could use to round to a certain frequency, e.g. `pd.Timestamp('2018-1-1 05:02:01').ceil('D')` -> `Timestamp('2018-01-02 00:00:00')`. – FObersteiner Jul 24 '20 at 12:25

2 Answers2

1

You can use replace function to replace the time part to make it floor and add one day to make it ceil

In [1]: import datetime

In [2]: def ceil(datetimeObj):
   ...:     return floor(datetimeObj) + datetime.timedelta(days=1)
   ...:

In [3]: def floor(datetimeObj):
   ...:     return datetimeObj.replace(second=0, hour=0, minute=0)
   ...:

In [4]: roughtime = datetime.datetime(2018,1,1,5,2,1)

In [5]: ceil(roughtime)
Out[5]: datetime.datetime(2018, 1, 2, 0, 0)

In [6]: floor(roughtime)
Out[6]: datetime.datetime(2018, 1, 1, 0, 0)
bigbounty
  • 16,526
  • 5
  • 37
  • 65
  • 2
    What about the case where datetime obj is ceiled already. It will bump 1 day. The other answer addresses this case. – Jérôme Jun 27 '22 at 08:08
1

You can use the datetime.combine(date, time) to create new datetime object using given datetime.date and datetime.time.

Floor

from datetime import datetime
floored = datetime.combine(roughtime.date(), datetime.min.time())

Ceil

from datetime import datetime, timedelta

if roughtime.time() == datetime.min.time():
    ceiled = roughtime
else:
    ceiled = datetime.combine(roughtime.date()+timedelta(days=1), datetime.min.time())
  • Ceiling needs if..else statement since if you would ceil 2020-07-24 00:00:00 one would not expect to get 2020-07-25 00:00:00
  • ceiled = roughtime is okay (no need to make a copy), since datetime objects are immutable. (source)
Niko Föhr
  • 28,336
  • 10
  • 93
  • 96