Skip to content

Commit

Permalink
Adding code to adjust for daylight savings time (#690)
Browse files Browse the repository at this point in the history
* Adding code to adjust for daylight savings time

* Fixing up comments
  • Loading branch information
sylviamclaughlin authored Nov 21, 2024
1 parent 743d527 commit ad0d4c7
Show file tree
Hide file tree
Showing 2 changed files with 118 additions and 2 deletions.
37 changes: 35 additions & 2 deletions app/integrations/google_workspace/google_calendar.py
Original file line number Diff line number Diff line change
Expand Up @@ -142,6 +142,9 @@ def find_first_available_slot(
# EST timezone
est = pytz.timezone("US/Eastern")

starting_hour = get_utc_hour(13, 0, "US/Eastern")
ending_hour = get_utc_hour(15, 0, "US/Eastern")

# Combine all busy times into a single list and sort them
busy_times = []
for calendar in freebusy_response["calendars"].values():
Expand All @@ -164,10 +167,10 @@ def find_first_available_slot(
continue

search_start = search_date.replace(
hour=17, minute=0, second=0, microsecond=0
hour=starting_hour, minute=0, second=0, microsecond=0
) # 1 PM EST, times are in UTC
search_end = search_date.replace(
hour=19, minute=0, second=0, microsecond=0
hour=ending_hour, minute=0, second=0, microsecond=0
) # 3 PM EST, times are in UTC

# if the day is a federal holiday, skip it
Expand Down Expand Up @@ -205,3 +208,33 @@ def get_federal_holidays():
for holiday in response.json()["holidays"]:
holidays.append(holiday["observedDate"])
return holidays


def get_utc_hour(hour, minute, tz_name, date=None):
"""
Converts a specific time in a given time zone to UTC and returns the hour.
Args:
hour (int): The hour of the time in 24-hour format.
minute (int): The minute of the time.
tz_name (str): The name of the time zone (e.g., "US/Eastern").
Returns:
str: The corresponding UTC hour.
"""
# Define the local timezone
local_tz = pytz.timezone(tz_name)

# If we are not passing the date, then initialize it to the current date:w
if date is None:
date = datetime.utcnow()

# Create a datetime object for the given time in the local timezone
local_time = local_tz.localize(
datetime(date.year, date.month, date.day, hour, minute)
)

# Convert to UTC
utc_time = local_time.astimezone(pytz.utc)

return utc_time.hour
83 changes: 83 additions & 0 deletions app/tests/integrations/google_workspace/test_google_calendar.py
Original file line number Diff line number Diff line change
Expand Up @@ -730,3 +730,86 @@ def test_leap_year_handling(requests_mock):

# Verify leap year is considered
assert "2024-02-29" in holidays, "Leap year date should be included in the holidays"


def test_get_utc_hour_same_zone():
"""
Test case for the same timezone (UTC).
"""
assert (
google_calendar.get_utc_hour(13, 0, "UTC") == 13
) # 1 PM UTC should remain 13 in UTC.


def test_get_utc_hour_us_eastern_daylight_time_winter():
"""
Test case for US Eastern Daylight Time during the winter
"""
# Explicitly set a date in December when daylight saving time is not active
tz_name = "US/Eastern"
local_tz = pytz.timezone(tz_name)
test_date = datetime(2023, 12, 1, 13, 0) # December 1, 2023, 1 PM EDT
localized_time = local_tz.localize(test_date)
utc_time = localized_time.astimezone(pytz.utc).hour

# Assert that 1 PM EDT is 6 PM UTC
assert google_calendar.get_utc_hour(13, 0, tz_name, test_date) == utc_time


def test_get_utc_hour_us_eastern_daylight_time_summer():
"""
Test case for US Eastern Daylight Time (EDT, UTC-4) during the summer.
"""
# Explicitly set a date in August when daylight saving time is active
tz_name = "US/Eastern"
local_tz = pytz.timezone(tz_name)
test_date = datetime(2023, 8, 1, 13, 0) # August 1, 2023, 1 PM EDT
localized_time = local_tz.localize(test_date)
utc_time = localized_time.astimezone(pytz.utc).hour

# Assert that 1 PM EDT is 5 PM UTC
assert google_calendar.get_utc_hour(13, 0, tz_name, test_date) == utc_time


def test_get_utc_hour_pacific_time():
"""
Test case for Pacific Standard Time (PST, UTC-8).
"""
test_date = datetime(2023, 12, 1, 13, 0) # December 1, 2023, 1 PM PDT

assert (
google_calendar.get_utc_hour(13, 0, "US/Pacific", test_date) == 21
) # 1 PM PST should be 9 PM UTC.


def test_get_utc_hour_with_invalid_timezone():
"""
Test case for invalid timezone input.
"""
with pytest.raises(pytz.UnknownTimeZoneError):
google_calendar.get_utc_hour(13, 0, "Invalid/Zone")


def test_get_utc_hour_midnight_transition():
"""
Test case for midnight transition.
"""
assert (
google_calendar.get_utc_hour(23, 0, "US/Eastern") == 4
) # 11 PM EST should be 4 AM UTC.


def test_get_utc_hour_negative_hour():
"""
Test case for invalid hour input.
"""
with pytest.raises(ValueError):
google_calendar.get_utc_hour(-1, 0, "UTC")


def test_get_utc_hour_invalid_minute():
"""
Test case for invalid minute input.
"""
with pytest.raises(ValueError):
google_calendar.get_utc_hour(13, 60, "UTC")

0 comments on commit ad0d4c7

Please sign in to comment.