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:
- Freeze the time forever at a specific date and time.
- Set the time to a designated datetime once, and then run the clock forward for every subsequent call.
- 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:
- The current working directory
- The project root directory
- 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.