diff --git a/osxphotos/_version.py b/osxphotos/_version.py index 3b5282c8..74d57efe 100644 --- a/osxphotos/_version.py +++ b/osxphotos/_version.py @@ -1,3 +1,3 @@ """ version info """ -__version__ = "0.33.4" +__version__ = "0.33.5" diff --git a/osxphotos/albuminfo.py b/osxphotos/albuminfo.py index 3084938f..7c77e3ce 100644 --- a/osxphotos/albuminfo.py +++ b/osxphotos/albuminfo.py @@ -57,7 +57,9 @@ class AlbumInfoBaseClass: self._creation_date_timestamp = self._db._dbalbum_details[uuid]["creation_date"] self._start_date_timestamp = self._db._dbalbum_details[uuid]["start_date"] self._end_date_timestamp = self._db._dbalbum_details[uuid]["end_date"] - self._local_tz = get_local_tz() + self._local_tz = get_local_tz( + datetime.fromtimestamp(self._creation_date_timestamp + TIME_DELTA) + ) @property def uuid(self): diff --git a/osxphotos/datetime_utils.py b/osxphotos/datetime_utils.py index 3ba6d0c4..f43fa59d 100644 --- a/osxphotos/datetime_utils.py +++ b/osxphotos/datetime_utils.py @@ -2,14 +2,23 @@ import datetime -def get_local_tz(): - """ return local timezone as datetime.timezone tzinfo """ - local_tz = ( - datetime.datetime.now(datetime.timezone(datetime.timedelta(0))) - .astimezone() - .tzinfo - ) - return local_tz + +def get_local_tz(dt): + """ return local timezone as datetime.timezone tzinfo for dt + + Args: + dt: datetime.datetime + + Returns: + local timezone for dt as datetime.timezone + + Raises: + ValueError if dt is not timezone naive + """ + if not datetime_has_tz(dt): + return dt.astimezone().tzinfo + else: + raise ValueError("dt must be naive datetime.datetime object") def datetime_remove_tz(dt): @@ -50,4 +59,4 @@ def datetime_naive_to_local(dt): f"{dt} has tzinfo {dt.tzinfo} and offset {dt.tizinfo.utcoffset(dt)}" ) - return dt.replace(tzinfo=get_local_tz()) + return dt.replace(tzinfo=get_local_tz(dt)) diff --git a/tests/test_catalina_10_15_6.py b/tests/test_catalina_10_15_6.py index ac449672..0ae421d4 100644 --- a/tests/test_catalina_10_15_6.py +++ b/tests/test_catalina_10_15_6.py @@ -1029,8 +1029,15 @@ def test_photosinfo_repr(): def test_from_to_date(): - import osxphotos + """ test from_date / to_date """ import datetime as dt + import os + import time + + import osxphotos + + os.environ["TZ"] = "US/Pacific" + time.tzset() photosdb = osxphotos.PhotosDB(PHOTOS_DB) @@ -1046,6 +1053,50 @@ def test_from_to_date(): assert len(photos) == 4 +def test_from_to_date_tz(): + """ Test from_date / to_date with and without timezone """ + import datetime as dt + import os + import time + + import osxphotos + + os.environ["TZ"] = "US/Pacific" + time.tzset() + + photosdb = osxphotos.PhotosDB(PHOTOS_DB) + + photos = photosdb.photos( + from_date=dt.datetime(2018, 9, 28, 13, 7, 0), + to_date=dt.datetime(2018, 9, 28, 13, 9, 0), + ) + assert len(photos) == 1 + assert photos[0].uuid == "D79B8D77-BFFC-460B-9312-034F2877D35B" + + photos = photosdb.photos( + from_date=dt.datetime( + 2018, + 9, + 28, + 16, + 7, + 0, + tzinfo=dt.timezone(dt.timedelta(days=-1, seconds=72000)), + ), + to_date=dt.datetime( + 2018, + 9, + 28, + 16, + 9, + 0, + tzinfo=dt.timezone(dt.timedelta(days=-1, seconds=72000)), + ), + ) + assert len(photos) == 1 + assert photos[0].uuid == "D79B8D77-BFFC-460B-9312-034F2877D35B" + + def test_date_invalid(): """ Test date is invalid """ from datetime import datetime, timedelta, timezone diff --git a/tests/test_datetime_utils.py b/tests/test_datetime_utils.py new file mode 100644 index 00000000..a2ec21d7 --- /dev/null +++ b/tests/test_datetime_utils.py @@ -0,0 +1,90 @@ +""" test datetime_utils """ +import pytest + + +def test_get_local_tz(): + """ test get_local_tz during time with no DST """ + import datetime + import os + import time + + from osxphotos.datetime_utils import get_local_tz + + os.environ["TZ"] = "US/Pacific" + time.tzset() + + dt = datetime.datetime(2018, 12, 31, 0, 0, 0) + local_tz = get_local_tz(dt) + assert local_tz == datetime.timezone( + datetime.timedelta(days=-1, seconds=57600), "PST" + ) + + +def test_get_local_tz_dst(): + """ test get_local_tz during time with DST """ + import datetime + import os + import time + + from osxphotos.datetime_utils import get_local_tz + + os.environ["TZ"] = "US/Pacific" + time.tzset() + + dt = datetime.datetime(2018, 6, 30, 0, 0, 0) + local_tz = get_local_tz(dt) + assert local_tz == datetime.timezone( + datetime.timedelta(days=-1, seconds=61200), "PDT" + ) + + +def test_datetime_remove_tz(): + """ test datetime_remove_tz """ + import datetime + + from osxphotos.datetime_utils import datetime_remove_tz + + dt = datetime.datetime( + 2018, + 12, + 31, + tzinfo=datetime.timezone(datetime.timedelta(days=-1, seconds=57600), "PST"), + ) + dt_no_tz = datetime_remove_tz(dt) + assert dt_no_tz.tzinfo is None + + +def test_datetime_has_tz(): + """ test datetime_has_tz """ + import datetime + + from osxphotos.datetime_utils import datetime_has_tz + + dt = datetime.datetime( + 2018, + 12, + 31, + tzinfo=datetime.timezone(datetime.timedelta(days=-1, seconds=57600), "PST"), + ) + assert datetime_has_tz(dt) + + dt_notz = datetime.datetime(2018, 12, 31) + assert not datetime_has_tz(dt_notz) + + +def test_datetime_naive_to_local(): + """ test datetime_naive_to_local """ + import datetime + import os + import time + + from osxphotos.datetime_utils import datetime_naive_to_local + + os.environ["TZ"] = "US/Pacific" + time.tzset() + + dt = datetime.datetime(2018, 6, 30, 0, 0, 0) + dt_local = datetime_naive_to_local(dt) + assert dt_local.tzinfo == datetime.timezone( + datetime.timedelta(days=-1, seconds=61200), "PDT" + )