Utils for dealing with time


flexmeasures.utils.time_utils.apply_offset_chain(dt: pd.Timestamp | datetime, offset_chain: str) pd.Timestamp | datetime

Apply an offset chain to a date.

An offset chain consist of multiple (pandas) offset strings separated by commas. Moreover, this function implements the offset string “DB”, which stands for Day Begin, to get a date from a datetime, i.e. removing time details finer than a day.


dt (pd.Timestamp | datetime) offset_chain (str)


pd.Timestamp | datetime (same type as given dt)

flexmeasures.utils.time_utils.as_server_time(dt: datetime) datetime

The datetime represented in the timezone of the FlexMeasures platform. If dt is naive, we assume it is UTC time.

flexmeasures.utils.time_utils.decide_resolution(start: datetime | None, end: datetime | None) str

Decide on a practical resolution given the length of the selected time period. Useful for querying or plotting.

flexmeasures.utils.time_utils.determine_minimum_resampling_resolution(event_resolutions: list[datetime.timedelta]) timedelta

Return minimum non-zero event resolution, or zero resolution if none of the event resolutions is non-zero.

flexmeasures.utils.time_utils.duration_isoformat(duration: timedelta)

Adapted version of isodate.duration_isoformat for formatting a datetime.timedelta.

The difference is that absolute days are not formatted as nominal days. Workaround for https://github.com/gweis/isodate/issues/74.

flexmeasures.utils.time_utils.ensure_local_timezone(dt: pd.Timestamp | datetime, tz_name: str = 'Europe/Amsterdam') pd.Timestamp | datetime

If no timezone is given, assume the datetime is in the given timezone and make it explicit. Otherwise, if a timezone is given, convert to that timezone.

flexmeasures.utils.time_utils.forecast_horizons_for(resolution: str | timedelta) list[str] | list[timedelta]

Return a list of horizons that are supported per resolution. Return values or of the same type as the input.

flexmeasures.utils.time_utils.freq_label_to_human_readable_label(freq_label: str) str

Translate pandas frequency labels to human-readable labels.

flexmeasures.utils.time_utils.get_first_day_of_next_month() datetime
flexmeasures.utils.time_utils.get_max_planning_horizon(resolution: timedelta) timedelta | None

Determine the maximum planning horizon for the given sensor resolution.

flexmeasures.utils.time_utils.get_most_recent_clocktime_window(window_size_in_minutes: int, now: datetime | None = None, grace_period_in_seconds: int | None = 0) tuple[datetime, datetime]

Calculate a recent time window, returning a 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)

We can demand a grace period (of x seconds) to have passed before we are ready to accept that we’re in a new window: Calling this function at 15:00:16 with window size 5 and grace period of 30 seconds -> (14:50:00, 14:55:00)

window_size_in_minutes is assumed to > 0 and < = 60, and a divisor of 60 (1, 2, …, 30, 60).

If now is not given, the current server time is used. if now / the current time lies within a boundary minute (e.g. 15 when window_size_in_minutes=5), then the window is not deemed over and the previous one is returned (in this case, [5, 10])

Returns two datetime objects. They’ll be in the timezone (if given) of the now parameter, or in the server timezone (see FLEXMEASURES_TIMEZONE setting).

flexmeasures.utils.time_utils.get_most_recent_hour() datetime
flexmeasures.utils.time_utils.get_most_recent_quarter() datetime
flexmeasures.utils.time_utils.get_timezone(of_user=False) BaseTzInfo

Return the FlexMeasures timezone, or if desired try to return the timezone of the current user.

flexmeasures.utils.time_utils.localized_datetime(dt: datetime) datetime

Localise a datetime to the timezone of the FlexMeasures platform. Note: this will change nothing but the tzinfo field.

flexmeasures.utils.time_utils.localized_datetime_str(dt: datetime, dt_format: str = '%Y-%m-%d %I:%M %p') str

Localise a datetime to the timezone of the FlexMeasures platform. If no datetime is passed in, use server_now() as basis.

Hint: This can be set as a jinja filter, so we can display local time in the app, e.g.: app.jinja_env.filters[‘localized_datetime’] = localized_datetime_str

flexmeasures.utils.time_utils.naive_utc_from(dt: datetime) datetime

Return a naive datetime, that is localised to UTC if it has a timezone. If dt is naive, we assume it is already in UTC time.

flexmeasures.utils.time_utils.naturalized_datetime_str(dt: datetime | None, now: datetime | None = None) str

Naturalise a datetime object (into a human-friendly string). The dt parameter (as well as the now parameter if you use it) can be either naive or tz-aware. We assume UTC in the naive case.

We use the the humanize library to generate a human-friendly string. If dt is not longer ago than 24 hours, we use humanize.naturaltime (e.g. “3 hours ago”), otherwise humanize.naturaldate (e.g. “one week ago”)

Hint: This can be set as a jinja filter, so we can display local time in the app, e.g.: app.jinja_env.filters[‘naturalized_datetime’] = naturalized_datetime_str

flexmeasures.utils.time_utils.resolution_to_hour_factor(resolution: str | timedelta) float

Return the factor with which a value needs to be multiplied in order to get the value per hour, e.g. 10 MW at a resolution of 15min are 2.5 MWh per time step.


resolution – timedelta or pandas offset such as “15T” or “1H”

flexmeasures.utils.time_utils.round_to_closest_hour(dt: datetime) datetime
flexmeasures.utils.time_utils.round_to_closest_quarter(dt: datetime) datetime
flexmeasures.utils.time_utils.server_now() datetime

The current time (timezone aware), converted to the timezone of the FlexMeasures platform.

flexmeasures.utils.time_utils.supported_horizons() list[datetime.timedelta]
flexmeasures.utils.time_utils.timedelta_to_pandas_freq_str(resolution: timedelta) str
flexmeasures.utils.time_utils.to_http_time(dt: pd.Timestamp | datetime) str

Formats datetime using the Internet Message Format fixdate.

>>> to_http_time(pd.Timestamp("2022-12-13 14:06:23Z"))
Tue, 13 Dec 2022 14:06:23 GMT


IMF-fixdate: https://www.rfc-editor.org/rfc/rfc7231#section-

flexmeasures.utils.time_utils.tz_index_naively(data: pd.DataFrame | pd.Series | pd.DatetimeIndex) pd.DataFrame | pd.Series | pd.DatetimeIndex

Turn any DatetimeIndex into a tz-naive one, then return. Useful for bokeh, for instance.