You are working with naive datetime
objects. For a naive datetime
object, the time is assumed to be in local time, and so your local system timezone offset is first applied. From the `datetime.timestamp() documentation:
Naive datetime
instances are assumed to represent local time and this method relies on the platform C mktime()
function to perform the conversion.
and further on:
Note: There is no method to obtain the POSIX timestamp directly from a naive datetime
instance representing UTC time. If your application uses this convention and your system timezone is not set to UTC, you can obtain the POSIX timestamp by supplying tzinfo=timezone.utc
:
timestamp = dt.replace(tzinfo=timezone.utc).timestamp()
Note that you can make your date calculation logic much easier by working with daetime.date
objects and using datetime.combine()
; this method also accepts a new timezone value, so you can pass in the timezone.utc
timezone at this stage:
from datetime import datetime, date, time, timedelta, timezone
# create first and last day of the month
first_day = date.today().replace(day=1)
last_day = (first_day + timedelta(days=31)).replace(day=1) - timedelta(days=1)
first_day = int(datetime.combine(first_day, time.min, tzinfo=timezone.utc).timestamp())
last_day = int(datetime.combine(last_day, time.min, tzinfo=timezone.utc).timestamp())
The above calculates the last day of the month by first adding 31 days (guaranteed to reach the next month whatever the current), then dropping that new date down to the first day of the month and then subtracting one day.
Demo:
>>> from datetime import datetime, date, time, timedelta, timezone
>>> first_day = date.today().replace(day=1)
>>> last_day = (first_day + timedelta(days=31)).replace(day=1) - timedelta(days=1)
>>> first_day, last_day
(datetime.date(2019, 1, 1), datetime.date(2019, 1, 31))
>>> int(datetime.combine(first_day, time.min, tzinfo=timezone.utc).timestamp())
1546300800
>>> int(datetime.combine(last_day, time.min, tzinfo=timezone.utc).timestamp())
1548892800
Note that midnight on the 31st of January leaves another 24 hours of the month left uncovered. You may want to remove the - timedelta(days=1)
subtraction off of the last_day
calculation above to switch to February 1st midnight (1548979200), or use time.max
to shift the timestamp to 23:23:59 (1 second before midnight) on the 31st (1548979199).