Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

add time_utils.get_recent_clock_time_window() function #135

Merged
merged 3 commits into from May 20, 2021
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
35 changes: 35 additions & 0 deletions flexmeasures/utils/tests/test_time_utils.py
Expand Up @@ -6,6 +6,7 @@
from flexmeasures.utils.time_utils import (
server_now,
naturalized_datetime_str,
get_most_recent_clocktime_window,
)


Expand Down Expand Up @@ -41,3 +42,37 @@ def test_naturalized_datetime_str(
h_ago = None
print(h_ago)
assert naturalized_datetime_str(h_ago, now=now) == exp_result


@pytest.mark.parametrize(
"window_size,now,exp_start,exp_end",
[
(
5,
datetime(2021, 4, 30, 15, 1),
datetime(2021, 4, 30, 14, 55),
datetime(2021, 4, 30, 15),
),
(
15,
datetime(2021, 4, 30, 3, 36),
datetime(2021, 4, 30, 3, 15),
datetime(2021, 4, 30, 3, 30),
),
(
10,
datetime(2021, 4, 30, 0, 5),
datetime(2021, 4, 29, 23, 50),
datetime(2021, 4, 30, 0, 0),
),
],
)
nhoening marked this conversation as resolved.
Show resolved Hide resolved
def test_recent_clocktime_window(window_size, now, exp_start, exp_end):
start, end = get_most_recent_clocktime_window(window_size, now=now)
assert start == exp_start
assert end == exp_end


def test_recent_clocktime_window_invalid_window():
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

120 minutes should also fail, right?
What about 0?

with pytest.raises(AssertionError):
get_most_recent_clocktime_window(25, now=datetime(2021, 4, 30, 3, 36))
26 changes: 25 additions & 1 deletion flexmeasures/utils/time_utils.py
@@ -1,5 +1,5 @@
from datetime import datetime, timedelta
from typing import List, Union, Optional
from typing import List, Union, Tuple, Optional

from flask import current_app
from flask_security.core import current_user
Expand Down Expand Up @@ -193,6 +193,30 @@ def get_most_recent_hour() -> datetime:
return now.replace(minute=now.minute - (now.minute % 60), second=0, microsecond=0)


def get_most_recent_clocktime_window(
window_size_in_minutes: int, now: Optional[datetime] = None
) -> Tuple[datetime, datetime]:
"""
Calculate a recent time window, choosing start and end minute so that
a full hour can be filled with such windows, e.g.:

Calling this function at 15:01:xx with window size 5 -> (14:55:00, 15:00:00)
Calling this function at 03:36:xx with window size 15 -> (03:15:00, 03:30:00)
"""
assert 60 % window_size_in_minutes == 0
if now is None:
now = datetime.now(tz=pytz.utc)
last_full_minute = now.replace(second=0, microsecond=0) - timedelta(minutes=1)
last_round_minute = last_full_minute.minute - (
last_full_minute.minute % window_size_in_minutes
)
begin_time = last_full_minute.replace(minute=last_round_minute) - timedelta(
minutes=window_size_in_minutes
)
end_time = begin_time + timedelta(minutes=window_size_in_minutes)
return begin_time, end_time


def get_default_start_time() -> datetime:
return get_most_recent_quarter() - timedelta(days=1)

Expand Down