Skip to content

Commit 2b395d2

Browse files
committed
Updates doc for timezones
1 parent 500f490 commit 2b395d2

File tree

1 file changed

+128
-0
lines changed

1 file changed

+128
-0
lines changed

docs/index.rst

Lines changed: 128 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1064,6 +1064,134 @@ level.
10641064
60
10651065
10661066
1067+
Timezones
1068+
=========
1069+
1070+
.. versionchanged:: 0.5
1071+
1072+
``Pendulum`` provides its own timezone handling and no longer
1073+
rely on ``pytz`` which was not always reliable.
1074+
1075+
Timezones are an important part of every datetime library and ``Pendulum``
1076+
tries to provide an easy and accurate system to handle them properly.
1077+
1078+
.. note::
1079+
1080+
The timezone system works best inside the ``pendulum`` ecosystem but
1081+
can also be used with the standard ``datetime`` library with a few limitations.
1082+
See `Using the timezone library directly`_
1083+
1084+
Normalization
1085+
-------------
1086+
1087+
When you create a ``Pendulum`` instance, the library will normalize it for the
1088+
given timezone to properly handle any transition that might have occurred.
1089+
1090+
.. code-block:: python
1091+
1092+
import pendulum
1093+
1094+
pendulum.create(2013, 3, 31, 2, 30, 0, 0, 'Europe/Paris')
1095+
# 2:30 for the 31th of March 2013 does not exist
1096+
# so pendulum will return the actual time which is 3:30+02:00
1097+
'2013-03-31T03:30:00+02:00'
1098+
1099+
pendulum.create(2013, 10, 27, 2, 30, 0, 0, 'Europe/Paris')
1100+
# Here, 2:30 exists twice in the day so pendulum will
1101+
# assume that the transition already occurred
1102+
'2013-10-27T02:30:00+01:00'
1103+
1104+
1105+
Shifting time to transition
1106+
---------------------------
1107+
1108+
So, what happens when you add time to a ``Pendulum`` instance and stumble upon
1109+
a transition time?
1110+
Well, ``Pendulum``, provided with the context of the previous instance, will
1111+
adopt the proper behavior and apply the transition accordingly.
1112+
1113+
.. code-block:: python
1114+
1115+
import pendulum
1116+
1117+
dt = pendulum.create(2013, 3, 31, 1, 59, 59, 999999, 'Europe/Paris')
1118+
'2013-03-31T01:59:59.999999+01:00'
1119+
dt = dt.add(microseconds=1)
1120+
'2013-03-31T03:00:00+02:00'
1121+
dt.subtract(microseconds=1)
1122+
'2013-03-31T01:59:59.999998+01:00'
1123+
1124+
dt = pendulum.create(2013, 10, 27, 1, 59, 59, 999999, 'Europe/Paris')
1125+
dt = dt.add(hours=1)
1126+
# We can't just do
1127+
# pendulum.create(2013, 10, 27, 2, 59, 59, 999999, 'Europe/Paris')
1128+
# because of the default normalization
1129+
'2013-10-27T02:59:59.999999+02:00'
1130+
dt = dt.add(microseconds=1)
1131+
'2013-10-27T02:00:00+01:00'
1132+
dt = dt.subtract(microseconds=1)
1133+
'2013-10-27T02:59:59.999999+02:00'
1134+
1135+
Switching timezones
1136+
-------------------
1137+
1138+
You can easily change the timezone of a ``Pendulum`` instance
1139+
with the ``in_timezone()`` method.
1140+
1141+
.. note::
1142+
1143+
You can also use the more concise ``in_tz()``
1144+
1145+
.. code-block:: python
1146+
1147+
in_paris = pendulum.create(2016, 8, 7, 22, 24, 30, tz='Europe/Paris')
1148+
'2016-08-07T22:24:30+02:00'
1149+
in_paris.in_timezone('America/New_York')
1150+
'2016-08-07T16:24:30-04:00'
1151+
in_paris.in_tz('Asia/Tokyo')
1152+
'2016-08-08T05:24:30+09:00'
1153+
1154+
Using the timezone library directly
1155+
-----------------------------------
1156+
1157+
Like said in the introduction, you can use the timezone library
1158+
directly with standard ``datetime`` objects but with limitations, especially
1159+
when adding and subtracting time around transition times.
1160+
1161+
.. code-block:: python
1162+
1163+
from datetime import datetime, timedelta
1164+
from pendulum import timezone
1165+
1166+
paris = timezone('Europe/Paris')
1167+
dt = datetime(2013, 3, 31, 2, 30)
1168+
dt = paris.convert(dt)
1169+
dt.isoformat()
1170+
'2013-03-31T03:30:00+02:00'
1171+
# Normalization works as expected
1172+
1173+
new_york = timezone('America/New_York')
1174+
new_york.convert(dt).isoformat()
1175+
'2013-03-30T21:30:00-04:00'
1176+
# Timezone switching works as expected
1177+
1178+
dt = datetime(2013, 3, 31, 1, 59, 59, 999999)
1179+
dt = paris.convert(dt)
1180+
dt.isoformat()
1181+
'2013-03-31T01:59:59.999999+01:00'
1182+
dt = dt + timedelta(microseconds=1)
1183+
dt.isoformat()
1184+
'2013-03-31T02:00:00+01:00'
1185+
# This does not work as expected.
1186+
# This is a limitation of datetime objects
1187+
# that can't switch around transition times.
1188+
# However, you can use convert()
1189+
# to retrieve the proper datetime.
1190+
dt = tz.convert(dt)
1191+
dt.isoformat()
1192+
'2013-03-31T03:00:00+02:00'
1193+
1194+
10671195
Interval
10681196
========
10691197

0 commit comments

Comments
 (0)