diff --git a/cylc/flow/rundb.py b/cylc/flow/rundb.py
index 1b04c43d3a2..cbe9c02e013 100644
--- a/cylc/flow/rundb.py
+++ b/cylc/flow/rundb.py
@@ -452,7 +452,9 @@ def close(self) -> None:
def connect(self) -> sqlite3.Connection:
"""Connect to the database."""
if self.conn is None:
- self.conn = sqlite3.connect(self.db_file_name, self.CONN_TIMEOUT)
+ self.conn = sqlite3.connect(
+ self.db_file_name, timeout=self.CONN_TIMEOUT
+ )
return self.conn
def create_tables(self):
diff --git a/cylc/flow/wallclock.py b/cylc/flow/wallclock.py
index c5b56419796..811f99d788a 100644
--- a/cylc/flow/wallclock.py
+++ b/cylc/flow/wallclock.py
@@ -16,11 +16,17 @@
"""Wall clock related utilities."""
from calendar import timegm
-from datetime import datetime, timedelta, timezone
-from typing import Dict, Optional
+from datetime import (
+ datetime,
+ timedelta,
+ timezone,
+)
from metomi.isodatetime.timezone import (
- get_local_time_zone_format, get_local_time_zone, TimeZoneFormatMode)
+ TimeZoneFormatMode,
+ get_local_time_zone,
+ get_local_time_zone_format,
+)
DATE_TIME_FORMAT_BASIC = "%Y%m%dT%H%M%S"
@@ -39,7 +45,6 @@
TIME_FORMAT_EXTENDED_SUB_SECOND = "%H:%M:%S.%f"
TIME_ZONE_STRING_UTC = "Z"
-TIME_ZONE_UTC_UTC_OFFSET = (0, 0)
TIME_ZONE_LOCAL_INFO = {
"hours": get_local_time_zone()[0],
@@ -51,8 +56,8 @@
}
TIME_ZONE_UTC_INFO = {
- "hours": TIME_ZONE_UTC_UTC_OFFSET[0],
- "minutes": TIME_ZONE_UTC_UTC_OFFSET[1],
+ "hours": 0,
+ "minutes": 0,
"string_basic": TIME_ZONE_STRING_UTC,
"string_extended": TIME_ZONE_STRING_UTC
}
@@ -70,8 +75,9 @@ def set_utc_mode(mode):
_FLAGS['utc_mode'] = bool(mode)
-def now(override_use_utc=None):
- """Return a current-time datetime.datetime and a UTC timezone flag.
+def now(override_use_utc: bool | None = None) -> tuple[datetime, bool]:
+ """Return a current-time, timezone-aware datetime.datetime and a flag
+ indicating whether it is UTC or not.
Keyword arguments:
override_use_utc (default None) - a boolean (or None) that, if
@@ -81,9 +87,9 @@ def now(override_use_utc=None):
"""
if override_use_utc or (override_use_utc is None and _FLAGS['utc_mode']):
- return datetime.utcnow(), False
+ return datetime.now(timezone.utc), False
else:
- return datetime.now(), True
+ return datetime.now().astimezone(), True
def get_current_time_string(display_sub_seconds=False, override_use_utc=None,
@@ -112,10 +118,9 @@ def get_current_time_string(display_sub_seconds=False, override_use_utc=None,
def get_time_string(
date_time: datetime,
display_sub_seconds: bool = False,
- override_use_utc: Optional[bool] = None,
+ override_use_utc: bool | None = None,
use_basic_format: bool = False,
date_time_is_local: bool = False,
- custom_time_zone_info: Optional[Dict] = None,
):
"""Return a string representing the current system time.
@@ -135,40 +140,10 @@ def get_time_string(
date_time_is_local:
Indicates that the date_time argument
object is in the local time zone, not UTC.
- custom_time_zone_info:
- A dictionary that enforces a particular time zone:
-
- .. code-block:: python
- {
- "hours": _hours, # offset from UTC
- "minutes": _minutes, # offset from utc
- "string_basic": _string, # timezone designators
- "string_extened": _string
- }
-
- Usage of ``string_basic`` or ``string_extended`` is
- switched by ``use_basic_format``.
"""
- time_zone_string = None
local_tz = get_local_time_zone()
- if custom_time_zone_info is not None:
- custom_hours = custom_time_zone_info["hours"]
- custom_minutes = custom_time_zone_info["minutes"]
- if use_basic_format:
- custom_string = custom_time_zone_info["string_basic"]
- else:
- custom_string = custom_time_zone_info["string_extended"]
- if date_time_is_local:
- date_time_hours, date_time_minutes = local_tz
- else:
- date_time_hours, date_time_minutes = (0, 0)
- diff_hours = custom_hours - date_time_hours
- diff_minutes = custom_minutes - date_time_minutes
- date_time = date_time + timedelta(
- hours=diff_hours, minutes=diff_minutes)
- time_zone_string = custom_string
- elif override_use_utc or (override_use_utc is None and _FLAGS['utc_mode']):
+ if override_use_utc or (override_use_utc is None and _FLAGS['utc_mode']):
time_zone_string = TIME_ZONE_STRING_UTC
if date_time_is_local:
date_time = date_time - timedelta(
@@ -198,9 +173,11 @@ def get_time_string(
return date_time_string + time_zone_string
-def get_time_string_from_unix_time(unix_time, display_sub_seconds=False,
- use_basic_format=False,
- custom_time_zone_info=None):
+def get_time_string_from_unix_time(
+ unix_time: float,
+ display_sub_seconds: bool = False,
+ use_basic_format: bool = False,
+) -> str:
"""Convert a unix timestamp into a local time zone datetime.datetime.
Arguments:
@@ -213,20 +190,15 @@ def get_time_string_from_unix_time(unix_time, display_sub_seconds=False,
use_basic_format (default False) - a boolean that, if True,
represents the date/time without "-" or ":" delimiters. This is
most useful for filenames where ":" may cause problems.
- custom_time_zone_info (default None) - a dictionary that enforces
- a particular time zone. It looks like {"hours": _hours,
- "minutes": _minutes, "string": _string} where _hours and _minutes
- are the hours and minutes offset from UTC and _string is the string
- to use as the time zone designator.
"""
- date_time = datetime.fromtimestamp(unix_time, timezone.utc)
- return get_time_string(date_time,
- display_sub_seconds=display_sub_seconds,
- use_basic_format=use_basic_format,
- override_use_utc=None,
- date_time_is_local=False,
- custom_time_zone_info=custom_time_zone_info)
+ return get_time_string(
+ datetime.fromtimestamp(unix_time, timezone.utc),
+ display_sub_seconds=display_sub_seconds,
+ use_basic_format=use_basic_format,
+ override_use_utc=None,
+ date_time_is_local=False,
+ )
def get_unix_time_from_time_string(datetime_string):
diff --git a/tests/conftest.py b/tests/conftest.py
index 3f31def2c9d..4fa4fe13d84 100644
--- a/tests/conftest.py
+++ b/tests/conftest.py
@@ -278,7 +278,7 @@ def set_timezone(monkeypatch):
Will use a very implausible timezone if none is provided.
"""
- def patch(time_zone: str = 'XXX-19:17'):
+ def patch(time_zone: str):
monkeypatch.setenv('TZ', time_zone)
time.tzset()
diff --git a/tests/unit/cycling/test_iso8601.py b/tests/unit/cycling/test_iso8601.py
index 7455e27f0ac..ea2a8de11a9 100644
--- a/tests/unit/cycling/test_iso8601.py
+++ b/tests/unit/cycling/test_iso8601.py
@@ -14,7 +14,10 @@
# You should have received a copy of the GNU General Public License
# along with this program. If not, see .
-from datetime import datetime
+from datetime import (
+ datetime,
+ timezone,
+)
import pytest
from pytest import param
@@ -892,10 +895,10 @@ def test_next_simple_no_now(set_cycling_type):
point = "next(T00Z)+P1D"
output = ingest_time(point, my_now)
- current_time = datetime.utcnow()
+ current_time = datetime.now(timezone.utc)
# my_now is None, but ingest_time will have used a similar time, and
# the returned value must be after current_time
- output_time = datetime.strptime(output, "%Y%m%dT%H%MZ")
+ output_time = datetime.strptime(output, "%Y%m%dT%H%M%z")
assert current_time < output_time
diff --git a/tests/unit/test_wallclock.py b/tests/unit/test_wallclock.py
index 83ffbf6d07f..f9302e00619 100644
--- a/tests/unit/test_wallclock.py
+++ b/tests/unit/test_wallclock.py
@@ -14,11 +14,16 @@
# You should have received a copy of the GNU General Public License
# along with this program. If not, see .
-from datetime import datetime
+from datetime import (
+ datetime,
+ timedelta,
+ timezone,
+)
+
+from metomi.isodatetime.data import CALENDAR
import pytest
from pytest import param
-from metomi.isodatetime.data import CALENDAR
from cylc.flow.wallclock import (
get_current_time_string,
get_time_string,
@@ -68,12 +73,28 @@ def test_get_unix_time_from_time_string_error(value, error):
get_unix_time_from_time_string(value)
+@pytest.mark.parametrize('tz_info', [
+ pytest.param(None, id="naive"),
+ pytest.param(timezone.utc, id="utc-tz-aware"),
+ pytest.param(timezone(timedelta(hours=5)), id="custom-tz-aware"),
+])
+def test_get_time_string_tzinfo(tz_info, set_timezone):
+ """Basic check it handles naive and timezone-aware datetime objects.
+
+ Currently we just ignore the timezone information in the datetime object.
+ """
+ set_timezone('UTC')
+ assert get_time_string(
+ datetime(2077, 2, 8, 13, 42, 39, 123456, tz_info)
+ ) == '2077-02-08T13:42:39Z'
+
+
def test_get_current_time_string(set_timezone):
"""It reacts to local time zone changes.
https://github.com/cylc/cylc-flow/issues/6701
"""
- set_timezone()
+ set_timezone('XXX-19:17')
res = get_current_time_string()
assert res[-6:] == '+19:17'
@@ -95,46 +116,12 @@ def test_get_current_time_string(set_timezone):
),
param(
datetime(2000, 12, 13, 15, 30, 12, 123456),
- {
- 'custom_time_zone_info': {
- 'hours': 0,
- 'minutes': -20,
- 'string_basic': 'XXX+00:20',
- },
- 'use_basic_format': True
- },
- '20001213T151012XXX+00:20',
- id='custom_time_zone_info_string_basic',
- ),
- param(
- datetime(2000, 12, 13, 15, 30, 12, 123456),
- {
- 'custom_time_zone_info': {
- 'hours': 0,
- 'minutes': -20,
- 'string_extended': ':UK/Exeter',
- },
- 'use_basic_format': False
- },
- '2000-12-13T15:10:12:UK/Exeter',
- id='custom_time_zone_info_string_extended',
- ),
- param(
- datetime(2000, 12, 13, 15, 30, 12, 123456),
- {
- 'custom_time_zone_info': {
- 'hours': 0,
- 'minutes': -20,
- 'string_extended': ':UK/Exeter',
- },
- 'use_basic_format': False,
- 'date_time_is_local': True,
- },
- '2000-12-12T19:53:12:UK/Exeter',
- id='date_time_is_local',
+ {'use_basic_format': True},
+ '20001214T104712+1917',
+ id='basic_format',
),
),
)
def test_get_time_string(set_timezone, arg, kwargs, expect):
- set_timezone()
+ set_timezone('XXX-19:17')
assert get_time_string(arg, **kwargs) == expect
diff --git a/tests/unit/tui/test_util.py b/tests/unit/tui/test_util.py
index 5d1a7f10e38..fb85858407a 100644
--- a/tests/unit/tui/test_util.py
+++ b/tests/unit/tui/test_util.py
@@ -17,7 +17,8 @@
from datetime import (
datetime,
- timedelta
+ timedelta,
+ timezone
)
from unittest.mock import Mock
@@ -171,7 +172,7 @@ def test_get_task_icon(
start_time = None
if start_offset is not None:
start_time = get_time_string(
- datetime.utcnow() - timedelta(seconds=start_offset)
+ datetime.now(timezone.utc) - timedelta(seconds=start_offset)
)
assert (
(