Skip to content

Date Helper

Class for simplyify date operations.

This class provides static methods to handle date formatting, parsing, and calculations.

This function supports a freeze time feature for testing purposes. See 'Freeze time feature' in the documentation below for more details.

add(dt_obj, **kwargs) staticmethod

Add a timedelta to a date or datetime object.

Parameters:

Name Type Description Default
dt_obj date | datetime

The date or datetime object to which the timedelta will be added.

required
**kwargs keyword arguments

The keyword arguments to pass to the timedelta constructor (e.g., days=1, hours=2).

{}

Raises:

Type Description
TypeError

If dt_obj is not a date or datetime object, or if the keyword arguments are not valid for a timedelta.

Returns:

Name Type Description
result date | datetime

A new date or datetime object with the added timedelta.

add_date(dt_obj, **kwargs) staticmethod

Add a timedelta to a date object.

Parameters:

Name Type Description Default
dt_obj date

The date object to which the timedelta will be added.

required
**kwargs keyword arguments

The keyword arguments to pass to the timedelta constructor (e.g., days=1, hours=2).

{}

Raises:

Type Description
TypeError

If dt_obj is not a date object, or if the keyword arguments are not valid for a timedelta.

Returns:

Name Type Description
result date

A new date object with the added timedelta.

add_datetime(dt_obj, **kwargs) staticmethod

Add a timedelta to a datetime object.

Parameters:

Name Type Description Default
dt_obj datetime

The datetime object to which the timedelta will be added.

required
**kwargs keyword arguments

The keyword arguments to pass to the timedelta constructor (e.g., days=1, hours=2).

{}

Raises:

Type Description
TypeError

If dt_obj is not a datetime object, or if the keyword arguments are not valid for a timedelta.

Returns:

Name Type Description
result datetime

A new datetime object with the added timedelta.

add_days(start_date, days) staticmethod

Add days to a date or datetime object.

Parameters:

Name Type Description Default
start_date date | datetime

The date/datetime to which days will be added.

required
days int

The number of days to add.

required

Returns:

Type Description
date | datetime | None

result (date | datetime) : A new date or datetime object with the added days, or None if start_date or days is None.

add_timezone(dt_obj, tzinfo=None) staticmethod

Add timezone information to a datetime object.

Parameters:

Name Type Description Default
dt_obj datetime

The datetime object to which the timezone information will be added.

required
tzinfo tzinfo

The timezone information to add to the datetime object. Defaults to the local timezone if not provided.

None

Raises:

Type Description
TypeError

If dt_obj is not a date or datetime object, or if the keyword arguments are not valid for a timedelta.

Returns:

Name Type Description
result datetime

A new datetime object with the added timezone information, or None if dt_obj is None or not a datetime object.

combine(date_obj, time_obj, tzinfo=None) staticmethod

Combine a date object and a time object into a datetime object.

Parameters:

Name Type Description Default
date_obj date

The date object to combine.

required
time_obj time

The time object to combine.

required
tzinfo tzinfo

The timezone information to add to the combined datetime object. Defaults to the local timezone if not provided.

None

Raises:

Type Description
TypeError

If date_obj is not a date object, or if time_obj is not a time object.

Returns:

Name Type Description
result datetime

A datetime object combining the date and time, with the specified timezone information.

convert_timezone(dt_obj, tzinfo=None) staticmethod

Convert a datetime object to a different timezone.

Parameters:

Name Type Description Default
dt_obj datetime

The datetime object to convert. Defaults to the local timezone if not provided.

required
tzinfo tzinfo

The timezone to which the datetime object will be converted. Defaults to the local timezone if not provided.

None

Raises:

Type Description
TypeError

If dt_obj is not a datetime object or if tzinfo is not a tzinfo object.

Returns:

Name Type Description
result datetime

A new datetime object representing the same moment in time as dt_obj, but with the specified timezone information.

days_between(start_date, end_date) staticmethod

Calculate the number of days between two date or datetime objects.

Parameters:

Name Type Description Default
start_date date

The start date.

required
end_date date

The end date.

required

Raises:

Type Description
TypeError

If start_date or end_date is not a date or datetime object.

Returns:

Name Type Description
difference int

The number of days between the two dates, or None if either date is None.

extract(dt_str, format_str=None, hide_tz=False, dt_type=None) staticmethod

Extract a date or datetime from a string.

format_str is optional. If not provided, the function will attempt to parse the string using the 'friendly date, datetime and time formats (see the format() function). If format_str is provided, it will be used to parse the string. If format_str is "ISO", the function will attempt to parse the string using the ISO 8601 format. If the string cannot be parsed using the provided format_str or the default formats, the function will raise a ValueError.

Parameters:

Name Type Description Default
dt_str str

The string to extract the date, datetime, or time from.

required
format_str Optional[str]

The format string to use for parsing the date, datetime, or time. If None, the function will attempt to parse the string using common date and datetime formats.

None
hide_tz bool

Whether to remove timezone information from the extracted datetime object. Defaults to False.

False
dt_type type

The type of object to extract (dt.date, dt.datetime, or dt.time). If provided, only that type will be attempted. If None, the function will attempt to parse the string as a datetime first, then a date, then a time.

None

Raises:

Type Description
ValueError

If the string cannot be parsed using the provided format_str or the default formats.

Returns:

Name Type Description
result date | datetime | time

A date, datetime or time object extracted from the string.

extract_date(dt_str, format_str=None, hide_tz=False) staticmethod

Extract a date from a string.

See extract() for more details.

Parameters:

Name Type Description Default
dt_str str

The string to extract the date from.

required
format_str Optional[str]

The format string to use for parsing the date. Defaults to None, which will attempt to parse using common date formats.

None
hide_tz bool

Whether to remove timezone information from the extracted datetime object. Defaults to False. Only applies if format_str is None or does not specify a date-only format.

False

Returns:

Name Type Description
result date

A date object extracted from the string.

extract_datetime(dt_str, format_str=None, hide_tz=False) staticmethod

Extract a date from a string.

See extract() for more details.

Parameters:

Name Type Description Default
dt_str str

The string to extract the datetime from.

required
format_str Optional[str]

The format string to use for parsing the datetime. Defaults to None, which will attempt to parse using common datetime formats.

None
hide_tz bool

Whether to remove timezone information from the extracted datetime object. Defaults to False. Only applies if format_str is None or does not specify a datetime-only format.

False

Returns:

Name Type Description
result datetime

A datetime object extracted from the string.

extract_time(dt_str, format_str=None, hide_tz=False) staticmethod

Extract a time from a string.

See extract() for more details.

Parameters:

Name Type Description Default
dt_str str

The string to extract the time from.

required
format_str Optional[str]

The format string to use for parsing the time. Defaults to None, which will attempt to parse using common time formats.

None
hide_tz bool

Whether to remove timezone information from the extracted time object. Defaults to False. Only applies if format_str is None or does not specify a time-only format.

False

Returns:

Name Type Description
result time

A time object extracted from the string.

format(dt_obj, format_str=None, hide_tz=True) staticmethod

Format a date object to a string.

If format_str is None, then dt_obj will use the default format according to it's type: date: %Y-%m-%d datetime: %Y-%m-%d %H:%M:%S time: %H:%M:%S The timezone will be included in the datetime string if it's included in dt_obj and hide_tz is False: datetime: %Y-%m-%d %H:%M:%S+11:00

If format_str is "ISO" then the ISO 8601 format will be used. date: %Y-%m-%d datetime: %Y-%m-%dT%H:%M:%S[TZ] time: %H:%M:%S The timezone will be included in the datetime string if it's included in dt_obj.

Parameters:

Name Type Description Default
dt_obj date | datetime | time

The date, datetime, or time object to format.

required
format_str str

The format string to use for formatting the date, datetime, or time.

None
hide_tz bool

Whether to hide the timezone information in the formatted string. Only applies to datetime objects when format_str is None. Defaults to True.

True

Raises:

Type Description
ValueError

If dt_obj is None or if format_str is not a valid format string for the type of dt_obj.

Returns:

Name Type Description
formatted_str str

The datetime object formatted as a string, or None if dt_obj is None or an unsupported type.

format_date(date_obj, date_format='%Y-%m-%d') staticmethod

Format a date object to a string.

Parameters:

Name Type Description Default
date_obj date | datetime

The date or datetime object to format.

required
date_format str

The format string to use for formatting the date or datetime.

'%Y-%m-%d'

Returns:

Name Type Description
date_str str

The formatted date string, or None if date_obj is None.

get_dawn_dusk_times(latitude, longitude, timezone=None, as_at=None) staticmethod

Get the dawn and dusk times based on the location returned from the specified shelly switch or the manually configured location configuration.

Parameters:

Name Type Description Default
latitude float

The latitude of the location.

required
longitude float

The longitude of the location.

required
timezone str

The timezone of the location. If not provided, the timezone will be determined based on the latitude and longitude.

None
as_at date

The date for which to get the dawn and dusk times. Defaults to today.

None

Returns:

Name Type Description
result dict

A dictionary containing the following keys: - as_date (date): The date for which the times are calculated. - timezone (str): The timezone of the location. - latitude (float): The latitude of the location. - longitude (float): The longitude of the location. - dawn (datetime): The dawn time. - sunrise (datetime): The sunrise time. - noon (datetime): The noon time. - sunset (datetime): The sunset time. - dusk (datetime): The dusk time.

get_file_date(file_path) staticmethod

Get the last modified date of a file.

Parameters:

Name Type Description Default
file_path str | Path

Path to the file. Can be a string or a Path object.

required

Returns:

Name Type Description
date_obj date

The last modified date of the file as a date object, or None if the file does not exist.

get_file_datetime(file_path) staticmethod

Get the last modified datetime of a file.

Parameters:

Name Type Description Default
file_path str | Path

Path to the file. Can be a string or a Path object.

required

Returns:

Name Type Description
datetime_obj datetime

The last modified datetime of the file as a date object, or None if the file does not exist.

get_local_timezone() staticmethod

Get the local timezone of the system.

Returns:

Name Type Description
tzinfo tzinfo

The local timezone of the system.

is_valid_date(date_str, format_str='%Y-%m-%d') staticmethod

Check if a date or datetime string is valid according to the specified format.

If format_str is "ISO", the function will attempt to parse the string using the ISO 8601 format.

Parameters:

Name Type Description Default
date_str str

The date string to check.

required
format_str Optional[str]

The format string to use for checking the date. Defaults to "%Y-%m-%d".

'%Y-%m-%d'

Returns:

Name Type Description
result bool

True if the date string is valid, False otherwise.

is_valid_datetime(dt_str, format_str='%Y-%m-%d %H:%M:%S') staticmethod

Check if a date or datetime string is valid according to the specified format.

If format_str is "ISO", the function will attempt to parse the string using the ISO 8601 format.

Parameters:

Name Type Description Default
dt_str str

The datetime string to check.

required
format_str Optional[str]

The format string to use for checking the datetime. Defaults to "%Y-%m-%d %H:%M:%S".

'%Y-%m-%d %H:%M:%S'

Returns:

Name Type Description
result bool

True if the datetime string is valid, False otherwise.

is_valid_time(time_str, format_str='%H:%M:%S') staticmethod

Check if a time string is valid according to the specified format.

If format_str is "ISO", the function will attempt to parse the string using the ISO 8601 format.

Parameters:

Name Type Description Default
time_str str

The time string to check.

required
format_str Optional[str]

The format string to use for checking the time. Defaults to "%H:%M:%S".

'%H:%M:%S'

Returns:

Name Type Description
result bool

True if the time string is valid, False otherwise.

midnight(dt_date=None, tzinfo=None) staticmethod

Get today's date at midnight.

Parameters:

Name Type Description Default
dt_date date

The date for which to get midnight. If None, today's date will be used.

None
tzinfo tzinfo

The timezone information to use for getting today's date at midnight. Defaults to the local timezone if not provided.

None

Returns:

Name Type Description
result datetime

Today's date at midnight as a datetime object, using the local timezone.

now(tzinfo=None) staticmethod

Get today's date and time.

Parameters:

Name Type Description Default
tzinfo tzinfo

The timezone information to use for getting the current datetime. Defaults to the local timezone if not provided.

None

Returns:

Name Type Description
result datetime

Today's date and time as a date object, using the local timezone.

now_str(format_str='%Y-%m-%d %H:%M:%S', tzinfo=None) staticmethod

Get the current time in string format.

If format_str is "ISO" then the ISO 8601 format will be used.

Parameters:

Name Type Description Default
format_str Optional[str]

The format string to use for formatting the datetime.

'%Y-%m-%d %H:%M:%S'
tzinfo tzinfo

The timezone information to use for getting the current datetime. Defaults to the local timezone if not provided.

None

Returns:

Name Type Description
result str

Current time as a formatted string, using the specified datetime format.

now_utc() staticmethod

Get today's date and time in UTC.

Returns:

Name Type Description
result datetime

Today's date and time as a date object, using UTC timezone.

Returns:

Name Type Description
result datetime

Today's date and time as a date object, using the local timezone.

parse_date(date_str, date_format='%Y-%m-%d') staticmethod

Parse a date string to a date or datetime object.

Parameters:

Name Type Description Default
date_str str

The date string to parse.

required
date_format Optional[str]

The format string to use for parsing the date. Defaults to "%Y-%m-%d".

'%Y-%m-%d'

Returns:

Name Type Description
date_obj date | datetime

A date or datetime object representing the parsed date_str, or None if date_str is empty.

remove_timezone(dt_obj) staticmethod

Remove timezone information from a datetime object.

Parameters:

Name Type Description Default
dt_obj datetime

The datetime object from which the timezone information will be removed.

required

Raises:

Type Description
TypeError

If dt_obj is not a date or datetime object.

Returns:

Name Type Description
result datetime

A new datetime object with the timezone information removed.

today(tzinfo=None) staticmethod

Get today's date.

Parameters:

Name Type Description Default
tzinfo tzinfo

The timezone information to use for getting today's date. Defaults to the local timezone if not provided.

None

Returns:

Name Type Description
result date

Today's date as a date object, using the local timezone.

today_add_days(days, tzinfo=None) staticmethod

Get today's date ofset by days.

Parameters:

Name Type Description Default
days int

The number of days to offset from today. Can be positive or negative

required
tzinfo tzinfo

The timezone information to use for getting today's date. Defaults to the local timezone if not provided.

None

Returns:

Name Type Description
result date

Today's date offset by the specified number of days.

today_str(format_str='%Y-%m-%d') staticmethod

Get today's date in string format.

If format_str is "ISO" then the ISO 8601 format will be used.

Parameters:

Name Type Description Default
format_str Optional[str]

The format string to use for formatting the date.

'%Y-%m-%d'

Returns:

Name Type Description
result str

Today's date as a formatted string, using the specified date format.

today_utc() staticmethod

Get today's date in UTC.

Returns:

Name Type Description
result date

Today's date as a date object, using UTC timezone.

Returns:

Name Type Description
result datetime

Today's date and time as a date object, using the local timezone.

Freeze time feature

The DateHelper functions that return the current system date or time - now(), now_str(), today(), today_add_days(), etc. - support a "freeze time feature". This allows the system date and time lookup to be modified in one of three ways:

  1. Freeze the time forever at a specific date and time.
  2. Set the time to a designated datetime once, and then run the clock forward for every subsequent call.
  3. Offset the current system date & time (positive or negative) by a set amount, for example +3 hours, -2 days, etc.

You can control this behaviour by creating a JSON file called freeze_time.json in one of the following locations:

  1. The current working directory
  2. The project root directory
  3. The [Project Root]/logs/ directory (if it exists)

The file must be structured as per the examples below.

  • Look for a freeze_time.json file in the project root folder.
  • If freeze_time = valid datetime and one_time = false, then every call to now() will return the same datetime
  • If freeze_time = valid datetime and one_time = true, then the first call to now() will return the specified datetime and each subsequent call will tick forward according to the normal clock.
  • If offset_time_unit and offset_time_amount are set, then use timedelta to adjust the time.

Example 1: Freeze the time forever at a specific date and time:

{
    "freeze_time": "2026-02-21T12:34:56",
    "one_time": false
}

The freeze_time key must be an ISO 8601 string and timezones are supported (e.g. "2026-04-01T12:34:56.789012+11:00"). If no timezone is supplied, the local timezone is assumed.

Example 2: Set the time to a designated datetime once, and then run the clock forward for every subsequent call.

{
    "freeze_time": "2026-02-21T12:34:56Z",
    "one_time": true
}

To accomplish this, DateHelper will rewrite the file to the example 3 format below after the first call for a system datetime.

Example 3: Offset the current system date & time by a set amount

{
    "offset_time_unit": "hours",
    "offset_time_amount": 3,
}

The offset_time_unit can be any time interval type supported by timedelta. The offset_time_amount can be a positive or negative decimal or whole number.

Other points to note

  • The freeze_time.json file must be writable.
  • If freeze_time and offset_time_amount are both set, freeze_time wins.
  • All other date, datetime, time related functions in this library that get the system time will also honor the freeze time functionality.