On Wed, Sep 1, 2021 at 1:55 AM dcs3spp via Python-list
<python-list@python.org> wrote:
>
> Hi,
>
> I wonder if anyone can help....
>
> I am struggling to understand the representation of timedelta when used in 
> conjunction with astimezone.
>
> Given the code below, in a python interactive interpreter, I am trying to 
> calculate a resultant datetime an hour earlier from a UTC datetime....
>
> ```bash
>     >>> dt = datetime(2021, 8, 22, 23, 59, 31, tzinfo=timezone.utc)
>     >>> hour_before=dt.astimezone(timezone(-timedelta(seconds=3600)))
>     >>> hour_before
>     datetime.datetime(2021, 8, 22, 22, 59, 31, 
> tzinfo=datetime.timezone(datetime.timedelta(days=-1, seconds=82800)))
> ```
>
> I cannot understand why the resultant datetime.timedelta is days=-1, 
> seconds=82800 (23 hours) .
>
> Why is it not an hour earlier as seconds=-3600? Why is days = -1 when the 
> resultant calculated date is the same, year, day, month??

It's consistent with modulo arithmetic:

>>> x = -3600
>>> x // 86400
-1
>>> x % 86400
82800

>>> help(datetime.timedelta)
...
 |  ----------------------------------------------------------------------
 |  Data descriptors defined here:
 |
 |  days
 |      Number of days.
 |
 |  microseconds
 |      Number of microseconds (>= 0 and less than 1 second).
 |
 |  seconds
 |      Number of seconds (>= 0 and less than 1 day).
 |
 |  ----------------------------------------------------------------------

The sub-day portions are guaranteed to be zero or above, meaning that
a small negative offset is described as "a day ago, plus 23 hours"
rather than "an hour ago". It's the exact same thing, though.

If you would prefer to see ALL components negative, just negate the
timedelta and then negate each component; that will give you an
equivalent timedelta.

>>> datetime.timedelta(seconds=-3600)
datetime.timedelta(days=-1, seconds=82800)
>>> -datetime.timedelta(seconds=-3600)
datetime.timedelta(seconds=3600)
>>> datetime.timedelta(seconds=-3600-86400)
datetime.timedelta(days=-2, seconds=82800)
>>> -datetime.timedelta(seconds=-3600-86400)
datetime.timedelta(days=1, seconds=3600)

Hope that explains it!

ChrisA
-- 
https://mail.python.org/mailman/listinfo/python-list

Reply via email to