Skip to content

Add timespec argument to to_iso8601_string() function #353

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 3 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
59 changes: 43 additions & 16 deletions pendulum/datetime.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
import calendar
import datetime
import pendulum
import platform

from typing import Union

Expand Down Expand Up @@ -37,24 +38,40 @@
W3C,
)

PYTHON_VERSION = platform.python_version()

class DateTime(datetime.datetime, Date):

# Formats

_FORMATS = {
"atom": ATOM,
"cookie": COOKIE,
"iso8601": lambda dt: dt.isoformat(),
"rfc822": RFC822,
"rfc850": RFC850,
"rfc1036": RFC1036,
"rfc1123": RFC1123,
"rfc2822": RFC2822,
"rfc3339": lambda dt: dt.isoformat(),
"rss": RSS,
"w3c": W3C,
}
if PYTHON_VERSION >= '3.6':
_FORMATS = {
"atom": ATOM,
"cookie": COOKIE,
"iso8601": lambda dt, timespec: dt.isoformat(timespec=timespec),
"rfc822": RFC822,
"rfc850": RFC850,
"rfc1036": RFC1036,
"rfc1123": RFC1123,
"rfc2822": RFC2822,
"rfc3339": lambda dt: dt.isoformat(),
"rss": RSS,
"w3c": W3C,
}
else:
_FORMATS = {
"atom": ATOM,
"cookie": COOKIE,
"iso8601": lambda dt: dt.isoformat(),
"rfc822": RFC822,
"rfc850": RFC850,
"rfc1036": RFC1036,
"rfc1123": RFC1123,
"rfc2822": RFC2822,
"rfc3339": lambda dt: dt.isoformat(),
"rss": RSS,
"w3c": W3C,
}

_EPOCH = datetime.datetime(1970, 1, 1, tzinfo=UTC)

Expand Down Expand Up @@ -364,13 +381,16 @@ def to_cookie_string(self):
"""
return self._to_string("cookie", locale="en")

def to_iso8601_string(self):
def to_iso8601_string(self, timespec="auto"):
"""
Format the instance as ISO 8601.

:param timespec: Specifies the number of additional components of the time to include
:type timespec: string

:rtype: str
"""
string = self._to_string("iso8601")
string = self._to_string("iso8601", timespec=timespec)

if self.tz and self.tz.name == "UTC":
string = string.replace("+00:00", "Z")
Expand Down Expand Up @@ -441,7 +461,7 @@ def to_w3c_string(self):
"""
return self._to_string("w3c")

def _to_string(self, fmt, locale=None):
def _to_string(self, fmt, locale=None, timespec=None):
"""
Format the instance to a common string format.

Expand All @@ -451,13 +471,20 @@ def _to_string(self, fmt, locale=None):
:param locale: The locale to use
:type locale: str or None

:param timespec: Specifies the number of additional components of the time to include
:type timespec: string

:rtype: str
"""
if fmt not in self._FORMATS:
raise ValueError("Format [{}] is not supported".format(fmt))

string_format = fmt

fmt = self._FORMATS[fmt]
if callable(fmt):
if string_format == "iso8601" and PYTHON_VERSION >= '3.6':
return fmt(self, timespec)
return fmt(self)

return self.format(fmt, locale=locale)
Expand Down
10 changes: 10 additions & 0 deletions tests/datetime/test_strings.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
# -*- coding: utf-8 -*-
import pendulum
import pytest
import platform

PYTHON_VERSION = platform.python_version()

def test_to_string():
d = pendulum.datetime(1975, 12, 25, 0, 0, 0, 0, tz="local")
Expand Down Expand Up @@ -52,6 +54,14 @@ def test_to_iso8601_extended_string():
d = pendulum.datetime(1975, 12, 25, 14, 15, 16, 123456, tz="local")
assert d.to_iso8601_string() == "1975-12-25T14:15:16.123456-05:00"

if PYTHON_VERSION >= '3.6':
def test_to_iso8601_string_timespec_hours():
d = pendulum.datetime(1975, 12, 25, 14, 15, 16, 123456, tz="local")
assert d.to_iso8601_string(timespec="hours") == "1975-12-25T14-05:00"

def test_to_iso8601_string_timespec_milliseconds():
d = pendulum.datetime(1975, 12, 25, 14, 15, 16, 123456, tz="local")
assert d.to_iso8601_string(timespec="milliseconds") == "1975-12-25T14:15:16.123-05:00"

def test_to_rfc822_string():
d = pendulum.datetime(1975, 12, 25, 14, 15, 16, tz="local")
Expand Down