Skip to content

Commit 02e8322

Browse files
committed
Add to_iso8601_string method for durations.
1 parent 53ab5e5 commit 02e8322

File tree

1 file changed

+48
-0
lines changed

1 file changed

+48
-0
lines changed

pendulum/duration.py

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
from pendulum.utils._compat import decode
1010

1111
from .constants import (
12+
DAYS_PER_WEEK,
1213
SECONDS_PER_DAY,
1314
SECONDS_PER_HOUR,
1415
SECONDS_PER_MINUTE,
@@ -243,6 +244,53 @@ def _sign(self, value):
243244

244245
return 1
245246

247+
def to_iso8601_string(self):
248+
"""
249+
Return the duration as an ISO8601 string.
250+
251+
Either:
252+
"PnYnMnDTnHnMnS"
253+
"PnW" - if only weeks are present
254+
"""
255+
rep = "P"
256+
if self._years:
257+
rep += "{}Y".format(self._years)
258+
if self._months:
259+
rep += "{}M".format(self._months)
260+
# days without any specified years, months
261+
days_alone = self._days - (self.years * 365 + self.months * 30)
262+
if days_alone:
263+
rep += "{}D".format(days_alone)
264+
time = "T"
265+
if self.hours:
266+
time += "{}H".format(self.hours)
267+
if self.minutes:
268+
time += "{}M".format(self.minutes)
269+
# TODO weeks
270+
# TODO signs and test
271+
s = ""
272+
if self.remaining_seconds:
273+
s = str(self.remaining_seconds)
274+
if self.microseconds:
275+
# no division to avoid possible floating point errors
276+
if not s:
277+
s = "0"
278+
s += ".{:0>6}".format(self.microseconds).rstrip("0")
279+
if s:
280+
time += "{}S".format(s)
281+
if len(time) > 1:
282+
rep += time
283+
if len(rep) == 1:
284+
# 0 duration
285+
rep = "PT0S"
286+
# check if PnW representation is suitable
287+
# i.e. only days
288+
# TODO abs?
289+
if (days_alone % DAYS_PER_WEEK == 0 and not self._years and not self._months and len(time) == 1):
290+
w = days_alone // DAYS_PER_WEEK
291+
rep = "P{}W".format(w)
292+
return rep
293+
246294
def as_timedelta(self):
247295
"""
248296
Return the interval as a native timedelta.

0 commit comments

Comments
 (0)