Compare commits
6 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
ed22105ec8 | ||
|
|
7c5af588c7 | ||
|
|
2690a285d9 | ||
|
|
bb60a570d0 | ||
|
|
ca0ab2d7d1 | ||
|
|
38bae7fb46 |
@@ -1,7 +1,7 @@
|
|||||||
# MARK: Project info
|
# MARK: Project info
|
||||||
[project]
|
[project]
|
||||||
name = "corelibs"
|
name = "corelibs"
|
||||||
version = "0.24.1"
|
version = "0.24.4"
|
||||||
description = "Collection of utils for Python scripts"
|
description = "Collection of utils for Python scripts"
|
||||||
readme = "README.md"
|
readme = "README.md"
|
||||||
requires-python = ">=3.13"
|
requires-python = ">=3.13"
|
||||||
|
|||||||
@@ -23,13 +23,17 @@ class TimestampStrings:
|
|||||||
|
|
||||||
TIME_ZONE: str = 'Asia/Tokyo'
|
TIME_ZONE: str = 'Asia/Tokyo'
|
||||||
|
|
||||||
def __init__(self, time_zone: str | None = None):
|
def __init__(self, time_zone: str | ZoneInfo | None = None):
|
||||||
self.timestamp_now = datetime.now()
|
self.timestamp_now = datetime.now()
|
||||||
self.time_zone = time_zone if time_zone is not None else self.TIME_ZONE
|
# set time zone as string
|
||||||
|
time_zone = time_zone if time_zone is not None else self.TIME_ZONE
|
||||||
|
self.time_zone = str(time_zone) if not isinstance(time_zone, str) else time_zone
|
||||||
|
# set ZoneInfo type
|
||||||
try:
|
try:
|
||||||
self.timestamp_now_tz = datetime.now(ZoneInfo(self.time_zone))
|
self.time_zone_zi = ZoneInfo(self.time_zone)
|
||||||
except ZoneInfoNotFoundError as e:
|
except ZoneInfoNotFoundError as e:
|
||||||
raise ValueError(f'Zone could not be loaded [{self.time_zone}]: {e}') from e
|
raise ValueError(f'Zone could not be loaded [{self.time_zone}]: {e}') from e
|
||||||
|
self.timestamp_now_tz = datetime.now(self.time_zone_zi)
|
||||||
self.today = self.timestamp_now.strftime('%Y-%m-%d')
|
self.today = self.timestamp_now.strftime('%Y-%m-%d')
|
||||||
self.timestamp = self.timestamp_now.strftime("%Y-%m-%d %H:%M:%S")
|
self.timestamp = self.timestamp_now.strftime("%Y-%m-%d %H:%M:%S")
|
||||||
self.timestamp_tz = self.timestamp_now_tz.strftime("%Y-%m-%d %H:%M:%S %Z")
|
self.timestamp_tz = self.timestamp_now_tz.strftime("%Y-%m-%d %H:%M:%S %Z")
|
||||||
|
|||||||
@@ -24,6 +24,7 @@ match_source_list=foo,bar
|
|||||||
element_a=Static energy
|
element_a=Static energy
|
||||||
element_b=123.5
|
element_b=123.5
|
||||||
element_c=True
|
element_c=True
|
||||||
|
elemend_d=AB:CD;EF
|
||||||
email=foo@bar.com,other+bar-fee@domain-com.cp,
|
email=foo@bar.com,other+bar-fee@domain-com.cp,
|
||||||
email_not_mandatory=
|
email_not_mandatory=
|
||||||
email_bad=gii@bar.com
|
email_bad=gii@bar.com
|
||||||
|
|||||||
@@ -4,10 +4,12 @@
|
|||||||
Test for double byte format
|
Test for double byte format
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
from zoneinfo import ZoneInfo
|
||||||
from corelibs.string_handling.timestamp_strings import TimestampStrings
|
from corelibs.string_handling.timestamp_strings import TimestampStrings
|
||||||
|
|
||||||
|
|
||||||
def main():
|
def main():
|
||||||
|
"""test"""
|
||||||
ts = TimestampStrings()
|
ts = TimestampStrings()
|
||||||
print(f"TS: {ts.timestamp_now}")
|
print(f"TS: {ts.timestamp_now}")
|
||||||
|
|
||||||
@@ -16,6 +18,14 @@ def main():
|
|||||||
except ValueError as e:
|
except ValueError as e:
|
||||||
print(f"Value error: {e}")
|
print(f"Value error: {e}")
|
||||||
|
|
||||||
|
ts = TimestampStrings("Europe/Vienna")
|
||||||
|
print(f"TZ: {ts.time_zone} -> TS: {ts.timestamp_now_tz}")
|
||||||
|
ts = TimestampStrings(ZoneInfo("Europe/Vienna"))
|
||||||
|
print(f"TZ: {ts.time_zone} -> TS: {ts.timestamp_now_tz}")
|
||||||
|
custom_tz = 'Europe/Paris'
|
||||||
|
ts = TimestampStrings(time_zone=custom_tz)
|
||||||
|
print(f"TZ: {ts.time_zone} -> TS: {ts.timestamp_now_tz}")
|
||||||
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
main()
|
main()
|
||||||
|
|||||||
@@ -3,7 +3,7 @@ PyTest: string_handling/timestamp_strings
|
|||||||
"""
|
"""
|
||||||
|
|
||||||
from datetime import datetime
|
from datetime import datetime
|
||||||
from unittest.mock import patch, MagicMock
|
from unittest.mock import patch
|
||||||
from zoneinfo import ZoneInfo
|
from zoneinfo import ZoneInfo
|
||||||
import pytest
|
import pytest
|
||||||
|
|
||||||
@@ -119,18 +119,55 @@ class TestTimestampStrings:
|
|||||||
assert ts2.time_zone == 'Europe/London'
|
assert ts2.time_zone == 'Europe/London'
|
||||||
assert ts1.time_zone != ts2.time_zone
|
assert ts1.time_zone != ts2.time_zone
|
||||||
|
|
||||||
@patch('corelibs.string_handling.timestamp_strings.ZoneInfo')
|
def test_zoneinfo_called_correctly_with_string(self):
|
||||||
def test_zoneinfo_called_correctly(self, mock_zoneinfo: MagicMock):
|
"""Test that ZoneInfo is called with correct timezone when passing string"""
|
||||||
"""Test that ZoneInfo is called with correct timezone"""
|
with patch('corelibs.string_handling.timestamp_strings.ZoneInfo') as mock_zoneinfo:
|
||||||
|
with patch('corelibs.string_handling.timestamp_strings.datetime') as mock_datetime:
|
||||||
|
mock_now = datetime(2023, 12, 25, 15, 30, 45)
|
||||||
|
mock_datetime.now.return_value = mock_now
|
||||||
|
|
||||||
|
custom_tz = 'Europe/Paris'
|
||||||
|
ts = TimestampStrings(time_zone=custom_tz)
|
||||||
|
assert ts.time_zone == custom_tz
|
||||||
|
|
||||||
|
mock_zoneinfo.assert_called_with(custom_tz)
|
||||||
|
|
||||||
|
def test_zoneinfo_object_parameter(self):
|
||||||
|
"""Test that ZoneInfo objects can be passed directly as timezone parameter"""
|
||||||
with patch('corelibs.string_handling.timestamp_strings.datetime') as mock_datetime:
|
with patch('corelibs.string_handling.timestamp_strings.datetime') as mock_datetime:
|
||||||
mock_now = datetime(2023, 12, 25, 15, 30, 45)
|
mock_now = datetime(2023, 12, 25, 15, 30, 45)
|
||||||
mock_datetime.now.return_value = mock_now
|
mock_now_tz = datetime(2023, 12, 25, 15, 30, 45, tzinfo=ZoneInfo('Europe/Paris'))
|
||||||
|
mock_datetime.now.side_effect = [mock_now, mock_now_tz]
|
||||||
|
|
||||||
custom_tz = 'Europe/Paris'
|
# Create a ZoneInfo object
|
||||||
ts = TimestampStrings(time_zone=custom_tz)
|
custom_tz_obj = ZoneInfo('Europe/Paris')
|
||||||
assert ts.time_zone == custom_tz
|
ts = TimestampStrings(time_zone=custom_tz_obj)
|
||||||
|
|
||||||
mock_zoneinfo.assert_called_with(custom_tz)
|
# The time_zone should be the ZoneInfo object itself
|
||||||
|
assert ts.time_zone_zi is custom_tz_obj
|
||||||
|
assert isinstance(ts.time_zone_zi, ZoneInfo)
|
||||||
|
|
||||||
|
def test_zoneinfo_object_vs_string_equivalence(self):
|
||||||
|
"""Test that ZoneInfo object and string produce equivalent results"""
|
||||||
|
with patch('corelibs.string_handling.timestamp_strings.datetime') as mock_datetime:
|
||||||
|
mock_now = datetime(2023, 12, 25, 15, 30, 45)
|
||||||
|
mock_now_tz = datetime(2023, 12, 25, 15, 30, 45, tzinfo=ZoneInfo('Europe/Paris'))
|
||||||
|
mock_datetime.now.side_effect = [mock_now, mock_now_tz, mock_now, mock_now_tz]
|
||||||
|
|
||||||
|
# Test with string
|
||||||
|
ts_string = TimestampStrings(time_zone='Europe/Paris')
|
||||||
|
|
||||||
|
# Test with ZoneInfo object
|
||||||
|
ts_zoneinfo = TimestampStrings(time_zone=ZoneInfo('Europe/Paris'))
|
||||||
|
|
||||||
|
# Both should produce the same timestamp formats (though time_zone attributes will differ)
|
||||||
|
assert ts_string.today == ts_zoneinfo.today
|
||||||
|
assert ts_string.timestamp == ts_zoneinfo.timestamp
|
||||||
|
assert ts_string.timestamp_file == ts_zoneinfo.timestamp_file
|
||||||
|
|
||||||
|
# The time_zone attributes will be different types but represent the same timezone
|
||||||
|
assert str(ts_string.time_zone) == 'Europe/Paris'
|
||||||
|
assert isinstance(ts_zoneinfo.time_zone_zi, ZoneInfo)
|
||||||
|
|
||||||
def test_edge_case_midnight(self):
|
def test_edge_case_midnight(self):
|
||||||
"""Test timestamp formatting at midnight"""
|
"""Test timestamp formatting at midnight"""
|
||||||
|
|||||||
Reference in New Issue
Block a user