From a36f781d74bd7c58517bc5aa19a7f3d5c334329a Mon Sep 17 00:00:00 2001 From: Steve C Date: Sun, 5 Nov 2023 22:03:50 -0500 Subject: [PATCH] Add DST detection for NeoFoodClub.is_outdated_lock (#6) --- neofoodclub/nfc.py | 6 +++++- neofoodclub/utils.py | 23 +++++++++++++++++++++++ tests/test_utils.py | 28 ++++++++++++++++++++++++++++ 3 files changed, 56 insertions(+), 1 deletion(-) diff --git a/neofoodclub/nfc.py b/neofoodclub/nfc.py index 076f97e..9d3fe31 100644 --- a/neofoodclub/nfc.py +++ b/neofoodclub/nfc.py @@ -347,7 +347,11 @@ def is_outdated_lock(self) -> bool: """:class:`bool`: Returns whether or not this round is to be considered over. 24 hours after the start time.""" if self.start is None: return True - return self.start <= datetime.datetime.now(tzutc()) - datetime.timedelta(days=1) + today = self.start.astimezone(tzutc()) + datetime.timedelta(days=1) + + difference = utils.get_dst_offset(today) + + return not (self.start <= datetime.datetime.now(tzutc()) <= today + difference) @property def is_over(self) -> bool: diff --git a/neofoodclub/utils.py b/neofoodclub/utils.py index 405ca8e..6a277c9 100644 --- a/neofoodclub/utils.py +++ b/neofoodclub/utils.py @@ -1,8 +1,10 @@ from __future__ import annotations +import datetime from typing import TYPE_CHECKING, Sequence import numpy as np +from dateutil import tz if TYPE_CHECKING: import numpy.typing as npt @@ -11,6 +13,7 @@ __all__ = ( "fix_bet_amounts", + "get_dst_offset", "Table", ) @@ -88,3 +91,23 @@ def fix_bet_amounts(amts: npt.NDArray[np.int32]) -> npt.NDArray[np.int32]: # fix any values below 50 to be 50, to maintain working bets # floor any values above max bet amount return np.clip(amts, math.BET_AMOUNT_MIN, math.BET_AMOUNT_MAX) + + +def get_dst_offset(today: datetime.datetime) -> datetime.timedelta: + """Gets the difference in daylight savings time offset between today and yesterday. + This is used to determine if the current time is during daylight savings time or not. + This allows the "outdated" checks to be more accurate. + """ + today = today.astimezone(tz.gettz("America/Los_Angeles")) + yesterday_offset = (today - datetime.timedelta(days=1)).utcoffset() + + today_offset = today.utcoffset() + + difference = datetime.timedelta(0) + if yesterday_offset is not None and today_offset is not None: + if yesterday_offset < today_offset: + difference = datetime.timedelta(hours=1) + if yesterday_offset > today_offset: + difference = datetime.timedelta(hours=-1) + + return difference diff --git a/tests/test_utils.py b/tests/test_utils.py index b3da440..dc36e7f 100644 --- a/tests/test_utils.py +++ b/tests/test_utils.py @@ -1,5 +1,9 @@ +import datetime + import numpy as np +from dateutil import tz +from neofoodclub import utils from neofoodclub.math import BET_AMOUNT_MAX, BET_AMOUNT_MIN from neofoodclub.nfc import NeoFoodClub from neofoodclub.utils import fix_bet_amounts @@ -76,3 +80,27 @@ def test_bets_stats_table_with_net_expected(nfc: NeoFoodClub) -> None: +--------+----------+------+--------+---------+----------+--------+-----+-----------+--------+----------+--------+------------+ """.strip() assert table == table_str + + +def test_dst_offset_fall_back() -> None: + # starting at America/New_York because I live there and I hate timezone math + offset = utils.get_dst_offset( + datetime.datetime(2023, 11, 5, 8, 0, 0, 0, tzinfo=tz.gettz("America/New_York")) + ) + assert offset == datetime.timedelta(hours=-1) + + +def test_dst_offset_spring_forward() -> None: + # starting at America/New_York because I live there and I hate timezone math + offset = utils.get_dst_offset( + datetime.datetime(2024, 3, 10, 8, 0, 0, 0, tzinfo=tz.gettz("America/New_York")) + ) + assert offset == datetime.timedelta(hours=1) + + +def test_dst_offset_no_dst() -> None: + # starting at America/New_York because I live there and I hate timezone math + offset = utils.get_dst_offset( + datetime.datetime(2024, 1, 1, 8, 0, 0, 0, tzinfo=tz.gettz("America/New_York")) + ) + assert offset == datetime.timedelta(hours=0)