When playing around with timezone conversions and dst impact, I have a hard time figuring out Pandas implementation of the fold parameter of the Timestamp constructor. The documentation mentions:
Due to daylight saving time, one wall clock time can occur twice when shifting from summer to winter time; fold describes whether the datetime-like corresponds to the first (0) or the second time (1) the wall clock hits the ambiguous time.
So far no surprise, but when I run the following code:
import pandas as pd
from datetime import datetime
pre_fold = pd.Timestamp(datetime(2022,10,30,1,30,0), tz="CET")
in_fold_fold0 = pd.Timestamp(datetime(2022,10,30,2,30,0), tz="CET")
in_fold_fold1 = pd.Timestamp(datetime(2022,10,30,2,30,0), tz="CET", fold=1)
post_fold = pd.Timestamp(datetime(2022,10,30,3,30,0), tz="CET")
print(f"fold0: {in_fold_fold0.fold}")
print(f"fold1: {in_fold_fold1.fold}")
print(f"Pre CET fold: {pre_fold} -> UTC {pre_fold.tz_convert(tz='UTC')}")
print(f"In CET fold, fold0: {in_fold_fold0} -> UTC {in_fold_fold0.tz_convert(tz='UTC')}")
print(f"In CET fold, fold1: {in_fold_fold1} -> UTC {in_fold_fold1.tz_convert(tz='UTC')}")
print(f"Post CET fold: {post_fold} -> UTC {post_fold.tz_convert(tz='UTC')}")
the output is not as expected:
fold0: 0
fold1: 1
Pre CET fold: 2022-10-30 01:30:00+02:00 -> UTC 2022-10-29 23:30:00+00:00
In CET fold, fold0: 2022-10-30 02:30:00+01:00 -> UTC 2022-10-30 01:30:00+00:00
In CET fold, fold1: 2022-10-30 02:30:00+01:00 -> UTC 2022-10-30 01:30:00+00:00
Post CET fold: 2022-10-30 03:30:00+01:00 -> UTC 2022-10-30 02:30:00+00:00
Line 4 should be:
In CET fold, fold0: 2022-10-30 02:30:00+02:00 -> UTC 2022-10-30 00:30:00+00:00
What am I missing here?
PS: Using python's datetime objects results in expected output:
from datetime import datetime
from dateutil import tz
dt_pre_fold = datetime(2022,10,30,1,30,0, tzinfo=tz.gettz("CET"))
dt_in_fold_fold0 = datetime(2022,10,30,2,30,0, tzinfo=tz.gettz("CET"))
dt_in_fold_fold1 = datetime(2022,10,30,2,30,0, tzinfo=tz.gettz("CET"), fold=1)
dt_post_fold = datetime(2022,10,30,3,30,0, tzinfo=tz.gettz("CET"))
print(f"Pre CET fold: {dt_pre_fold} -> UTC {dt_pre_fold.astimezone(tz.gettz('UTC'))}")
print(f"In CET fold, fold0: {dt_in_fold_fold0} -> UTC {dt_in_fold_fold0.astimezone(tz.gettz('UTC'))}")
print(f"In CET fold, fold1: {dt_in_fold_fold1} -> UTC {dt_in_fold_fold1.astimezone(tz.gettz('UTC'))}")
print(f"Post CET fold: {dt_post_fold} -> UTC {dt_post_fold.astimezone(tz.gettz('UTC'))}")
Output:
Pre CET fold: 2022-10-30 01:30:00+02:00 -> UTC 2022-10-29 23:30:00+00:00
In CET fold, fold0: 2022-10-30 02:30:00+02:00 -> UTC 2022-10-30 00:30:00+00:00
In CET fold, fold1: 2022-10-30 02:30:00+01:00 -> UTC 2022-10-30 01:30:00+00:00
Post CET fold: 2022-10-30 03:30:00+01:00 -> UTC 2022-10-30 02:30:00+00:00