Skip to content

Commit

Permalink
Allow parsing datetime string without explicit UTC offset (timezone)
Browse files Browse the repository at this point in the history
Fixes #299
  • Loading branch information
anthrotype committed Dec 18, 2017
1 parent 0501a54 commit fa9cdc8
Show file tree
Hide file tree
Showing 2 changed files with 34 additions and 4 deletions.
18 changes: 14 additions & 4 deletions Lib/glyphsLib/types.py
Original file line number Diff line number Diff line change
Expand Up @@ -223,12 +223,24 @@ def plistValue(self):
class glyphs_datetime(baseType):
"""Read/write a datetime. Doesn't maintain time zone offset."""

utc_offset_re = re.compile(
r".* (?P<sign>\+|\-)(?P<hours>\d\d)(?P<minutes>\d\d)$")

def read(self, src):
src = src.replace('"', '')
"""Parse a datetime object from a string."""
string = src.replace('"', '')
# parse timezone ourselves, since %z is not always supported
# see: http://bugs.python.org/issue6641
string, tz = src.rsplit(' ', 1)
m = glyphs_datetime.utc_offset_re.match(string)
if m:
sign = 1 if m.group("sign") == "+" else -1
tz_hours = sign * int(m.group("hours"))
tz_minutes = sign * int(m.group("minutes"))
offset = datetime.timedelta(hours=tz_hours, minutes=tz_minutes)
string = string[:-6]
else:
# no explicit timezone
offset = datetime.timedelta(0)
if 'AM' in string or 'PM' in string:
datetime_obj = datetime.datetime.strptime(
string, '%Y-%m-%d %I:%M:%S %p'
Expand All @@ -237,8 +249,6 @@ def read(self, src):
datetime_obj = datetime.datetime.strptime(
string, '%Y-%m-%d %H:%M:%S'
)
offset = datetime.timedelta(
hours=int(tz[:3]), minutes=int(tz[0] + tz[3:]))
return datetime_obj + offset

def plistValue(self):
Expand Down
20 changes: 20 additions & 0 deletions tests/types_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,26 @@ def test_parsing_12hr_format(self):
self.assertEqual(test_time.read(string_12hrs),
datetime.datetime(2017, 1, 1, 17, 30, 30))

def test_parsing_timezone(self):
"""Assert glyphs_datetime can parse the (optional) timezone
formatted as UTC offset. If it's not explicitly specified, then
+0000 is assumed.
"""
self.assertEqual(glyphs_datetime().read('2017-12-18 16:45:31 -0100'),
datetime.datetime(2017, 12, 18, 15, 45, 31))

self.assertEqual(glyphs_datetime().read('2017-12-18 14:15:31 +0130'),
datetime.datetime(2017, 12, 18, 15, 45, 31))

self.assertEqual(glyphs_datetime().read('2017-12-18 15:45:31'),
datetime.datetime(2017, 12, 18, 15, 45, 31))

self.assertEqual(glyphs_datetime().read('2017-12-18 03:45:31 PM'),
datetime.datetime(2017, 12, 18, 15, 45, 31))

self.assertEqual(glyphs_datetime().read('2017-12-18 09:45:31 AM'),
datetime.datetime(2017, 12, 18, 9, 45, 31))


if __name__ == '__main__':
unittest.main()

0 comments on commit fa9cdc8

Please sign in to comment.