diff --git a/fiftyone/core/fields.py b/fiftyone/core/fields.py index 64eea2ff4d6..c3b5b0de377 100644 --- a/fiftyone/core/fields.py +++ b/fiftyone/core/fields.py @@ -516,8 +516,14 @@ def to_python(self, value): # Explicitly converting to UTC is important here because PyMongo loads # everything as `datetime`, which will respect `fo.config.timezone`, - # but we always need UTC here for the conversion back to `date` - return value.astimezone(pytz.utc).date() + # but we always need UTC here for the conversion back to `date` because + # we write to the DB in UTC time. + # If value is timezone unaware, then do not convert because it will be + # assumed to be in local timezone and date will be wrong for GMT+ + # localities. + if value.tzinfo is not None: + value = value.astimezone(pytz.utc) + return value.date() def validate(self, value): if not isinstance(value, date): diff --git a/fiftyone/core/odm/database.py b/fiftyone/core/odm/database.py index b875fc4631b..8f0d40f13f6 100644 --- a/fiftyone/core/odm/database.py +++ b/fiftyone/core/odm/database.py @@ -422,7 +422,7 @@ def get_async_db_conn(use_global=False): def _apply_options(db): timezone = fo.config.timezone - if not timezone or timezone.lower() == "utc": + if not timezone: return db if timezone.lower() == "local": diff --git a/tests/unittests/dataset_tests.py b/tests/unittests/dataset_tests.py index e581b3ecfc3..ef69954f972 100644 --- a/tests/unittests/dataset_tests.py +++ b/tests/unittests/dataset_tests.py @@ -5,6 +5,7 @@ | `voxel51.com `_ | """ +import time from copy import deepcopy, copy from datetime import date, datetime, timedelta import gc @@ -558,6 +559,22 @@ def test_date_fields(self): self.assertEqual(type(sample.date), date) self.assertEqual(int((sample.date - date1).total_seconds()), 0) + # Now change system time to something GMT+ + system_timezone = os.environ.get("TZ") + try: + os.environ["TZ"] = "Europe/Madrid" + time.tzset() + dataset.reload() + finally: + if system_timezone is None: + del os.environ["TZ"] + else: + os.environ["TZ"] = system_timezone + time.tzset() + + self.assertEqual(type(sample.date), date) + self.assertEqual(int((sample.date - date1).total_seconds()), 0) + @drop_datasets def test_datetime_fields(self): dataset = fo.Dataset()