gws.lib.datetimex

Date and time utilities.

These utilities are wrappers around the datetime module. Some functions also use pendulum (https://pendulum.eustace.io/), however all functions here return stock datetime.datetime objects, and all returned objects are timezone-aware.

Functions in this package fall into these groups:

  • time zones: time_zone, is_valid_time_zone, set_local_time_zone,

  • constructors and parsers: new, now, today, parse, from_string, from_iso_string, from_timestamp and others,

  • formatters: to_iso_string, to_iso_date_string, to_basic_string, to_string and others,

  • converters: to_timestamp, to_millis, to_utc, to_local, to_time_zone,

  • predicates: is_date, is_datetime, is_utc, is_local,

  • arithmetic: add, difference, total_difference, next, prev,

  • wrappers for pendulum helpers: start_of_<unit> and end_of_<unit> (for second, minute, hour, day, week, month, year), day_of_week, day_of_year, week_of_month, week_of_year, days_in_month,

  • durations: parse_duration, format_duration.

Time zones are given as zoneinfo strings, like Europe/Berlin. An empty string (the default) means the local time zone. Alias names like CEST are not supported.

When a function accepts a date or time argument, it is converted to a datetime as follows:

  • None means the current date and time,

  • naive datetime objects are assumed to be in the local time zone,

  • date objects are promoted to datetime with the time set to midnight UTC,

  • time objects are promoted to datetime with today’s date.

Parsers (parse, from_string etc.) attach the given time zone to naive input, and a parsed date becomes midnight in that time zone.

When running in a docker container, there are several ways to set up the local time zone:

  • by setting the config variable server.timeZone (see gws.config.parser),

  • by setting the TZ environment variable,

  • by mounting a host zone info file to /etc/localtime.

Example:

import gws.lib.datetimex as datetimex

d = datetimex.parse('2024-05-01T12:30:00', tz='Europe/Berlin')
datetimex.to_iso_string(d)  # '2024-05-01T12:30:00+0200'
datetimex.to_iso_string(datetimex.to_utc(d), with_tz='Z')  # '2024-05-01T10:30:00Z'

next_week = datetimex.add(d, weeks=1)
datetimex.parse_duration('1h30m')  # 5400

Source code: gws.lib.datetimex

Package Contents

gws.lib.datetimex.add(d: datetime.date | None = None, years=0, months=0, days=0, weeks=0, hours=0, minutes=0, seconds=0, microseconds=0) → datetime.datetime

Add a duration to a date.

Negative values subtract.

Parameters:
  • d – Base date, the current date and time by default.

  • years – Years to add.

  • months – Months to add.

  • days – Days to add.

  • weeks – Weeks to add.

  • hours – Hours to add.

  • minutes – Minutes to add.

  • seconds – Seconds to add.

  • microseconds – Microseconds to add.

Returns:

The resulting datetime.

gws.lib.datetimex.day_of_week(d: datetime.date | None = None) → int
gws.lib.datetimex.day_of_year(d: datetime.date | None = None) → int
gws.lib.datetimex.days_in_month(d: datetime.date | None = None) → int
class gws.lib.datetimex.Diff

Difference between two dates, as returned by difference and total_difference.

days: int

Days.

hours: int

Hours.

microseconds: int

Microseconds.

minutes: int

Minutes.

months: int

Months.

seconds: int

Seconds.

weeks: int

Weeks.

years: int

Years.

gws.lib.datetimex.difference(d1: datetime.date, d2: datetime.date | None = None) → Diff

Compute the difference between two dates, broken down into components.

The components add up to the whole difference, for example 1 year, 2 months, 1 week, 3 days.

Parameters:
  • d1 – The start date.

  • d2 – The end date, the current date and time by default.

Returns:

The difference from d1 to d2.

gws.lib.datetimex.end_of_day(d: datetime.date | None = None) → datetime.datetime
gws.lib.datetimex.end_of_hour(d: datetime.date | None = None) → datetime.datetime
gws.lib.datetimex.end_of_minute(d: datetime.date | None = None) → datetime.datetime
gws.lib.datetimex.end_of_month(d: datetime.date | None = None) → datetime.datetime
gws.lib.datetimex.end_of_second(d: datetime.date | None = None) → datetime.datetime
gws.lib.datetimex.end_of_week(d: datetime.date | None = None) → datetime.datetime
gws.lib.datetimex.end_of_year(d: datetime.date | None = None) → datetime.datetime
exception gws.lib.datetimex.Error

Bases: gws.Error

Date and time error.

gws.lib.datetimex.format_duration(s: int) → str

Format a duration in seconds to a string.

Parameters:

s – Duration in seconds.

Returns:

A string like 1d 2h 30m, or 0s for a zero duration.

gws.lib.datetimex.from_iso_string(s: str, tz: str = '') → datetime.datetime

Parse an ISO 8601 date or datetime string.

A date without time becomes midnight in the given time zone.

Parameters:
  • s – ISO 8601 date or datetime string.

  • tz – Time zone for timezone-naive inputs, the local time zone by default.

Returns:

A datetime.

Raises:

Error – If the string cannot be parsed or is not a date or datetime.

gws.lib.datetimex.from_iso_time_string(s: str, tz: str = '') → datetime.datetime

Parse an ISO 8601 time string into a datetime with today’s date.

Parameters:
  • s – ISO 8601 time string.

  • tz – Time zone for timezone-naive inputs, the local time zone by default.

Returns:

A datetime.

Raises:

Error – If the string cannot be parsed or is not a time.

gws.lib.datetimex.from_string(s: str, tz: str = '') → datetime.datetime

Parse a date or datetime string.

Accepts ISO 8601 and some other common formats understood by pendulum. A date without time becomes midnight in the given time zone.

Parameters:
  • s – Date or datetime string.

  • tz – Time zone for timezone-naive inputs, the local time zone by default.

Returns:

A datetime.

Raises:

Error – If the string cannot be parsed or is not a date or datetime.

gws.lib.datetimex.from_timestamp(n: float, tz: str = '') → datetime.datetime

Create a datetime from a Unix timestamp.

Parameters:
  • n – Unix timestamp, in seconds since the epoch.

  • tz – Time zone string, the local time zone by default.

Returns:

A datetime in the given time zone.

gws.lib.datetimex.is_date(x) → bool

Check if an object is a date.

Parameters:

x – Object to check.

Returns:

True if the object is a date. Since datetime is a subclass of date, this is also True for datetimes.

gws.lib.datetimex.is_datetime(x) → bool

Check if an object is a datetime.

Parameters:

x – Object to check.

Returns:

True if the object is a datetime.

gws.lib.datetimex.is_local(d: datetime.datetime) → bool

Check if a datetime is in the local time zone.

Parameters:

d – Datetime to check. A naive datetime is assumed to be local.

Returns:

True if the time zone of the datetime is the local time zone.

gws.lib.datetimex.is_utc(d: datetime.datetime) → bool

Check if a datetime is in the UTC time zone.

Parameters:

d – Datetime to check. A naive datetime is assumed to be local.

Returns:

True if the time zone of the datetime is UTC.

gws.lib.datetimex.is_valid_time_zone(tz: str) → bool

Check if a time zone string is valid.

Parameters:

tz – Time zone string, like Europe/Berlin.

Returns:

True if the time zone is known.

gws.lib.datetimex.mock_now(d)

Context manager that makes all functions here use a fixed current date and time, for testing.

Parameters:

d – Datetime to use as the current date and time.

gws.lib.datetimex.new(year, month, day, hour=0, minute=0, second=0, microsecond=0, fold=0, tz: str = '') → datetime.datetime

Create a new datetime object with the specified components.

Parameters:
  • year – Year.

  • month – Month.

  • day – Day.

  • hour – Hour.

  • minute – Minute.

  • second – Second.

  • microsecond – Microsecond.

  • fold – Fold value for ambiguous local times, see datetime.datetime.

  • tz – Time zone string, the local time zone by default.

Returns:

A timezone-aware datetime.

Raises:

Error – If the time zone is invalid.

gws.lib.datetimex.next(day: int | str, d: datetime.date | None = None, keep_time=False) → datetime.datetime

Get the next occurrence of a specific weekday.

Parameters:
  • day – Day of the week, 0 to 6 for Monday to Sunday, or a lowercase weekday name like monday.

  • d – Starting date, the current date and time by default.

  • keep_time – Keep the time of the starting date, otherwise the time is set to midnight.

Returns:

The datetime of the next occurrence after the starting date.

gws.lib.datetimex.now(tz: str = '') → datetime.datetime

Get the current date and time.

Parameters:

tz – Time zone string, the local time zone by default.

Returns:

The current datetime in the given time zone.

gws.lib.datetimex.now_utc() → datetime.datetime

Get the current date and time in UTC.

Returns:

The current datetime in UTC.

gws.lib.datetimex.parse(s: str | datetime.datetime | datetime.date | None, tz: str = '') → datetime.datetime | None

Parse a string, datetime, or date into a datetime object.

Strings are parsed like in from_string. Dates become midnight in the given time zone.

Parameters:
  • s – Input to parse.

  • tz – Time zone for timezone-naive inputs, the local time zone by default.

Returns:

A datetime, or None if the input is empty or cannot be parsed.

gws.lib.datetimex.parse_duration(s: str) → int

Convert a duration string to seconds.

The string consists of numbers followed by units w, d, h, m or s, like 1w2d3h4m5s. A trailing number without a unit is taken as seconds.

Parameters:

s – Duration string, or an integer number of seconds, which is returned as is.

Returns:

The duration in seconds.

Raises:

Error – If the string is not a valid duration.

gws.lib.datetimex.parse_time(s: str | datetime.time | None, tz: str = '') → datetime.datetime | None

Parse a string or time into a datetime object with today’s date.

Strings are parsed like in from_iso_time_string.

Parameters:
  • s – Input to parse.

  • tz – Time zone for timezone-naive inputs, the local time zone by default.

Returns:

A datetime, or None if the input is empty or cannot be parsed.

gws.lib.datetimex.prev(day: int | str, d: datetime.date | None = None, keep_time=False) → datetime.datetime

Get the previous occurrence of a specific weekday.

Parameters:
  • day – Day of the week, 0 to 6 for Monday to Sunday, or a lowercase weekday name like monday.

  • d – Starting date, the current date and time by default.

  • keep_time – Keep the time of the starting date, otherwise the time is set to midnight.

Returns:

The datetime of the previous occurrence before the starting date.

gws.lib.datetimex.set_local_time_zone(tz: str)

Set the local time zone for the system.

The time zone is set by linking /etc/localtime to the zone info file, which requires root privileges. Nothing is done if the time zone is already set.

Parameters:

tz – Time zone string, like Europe/Berlin.

Raises:

Error – If the time zone is invalid, or the process is not running as root.

gws.lib.datetimex.start_of_day(d: datetime.date | None = None) → datetime.datetime
gws.lib.datetimex.start_of_hour(d: datetime.date | None = None) → datetime.datetime
gws.lib.datetimex.start_of_minute(d: datetime.date | None = None) → datetime.datetime
gws.lib.datetimex.start_of_month(d: datetime.date | None = None) → datetime.datetime
gws.lib.datetimex.start_of_second(d: datetime.date | None = None) → datetime.datetime
gws.lib.datetimex.start_of_week(d: datetime.date | None = None) → datetime.datetime
gws.lib.datetimex.start_of_year(d: datetime.date | None = None) → datetime.datetime
gws.lib.datetimex.time_to_iso_string(d: datetime.date | datetime.time | None = None) → str

Convert a date or time to a time string without time zone.

Parameters:

d – Datetime or time to convert. For a date or None, 00:00:00 is returned.

Returns:

A string like 12:30:00.

gws.lib.datetimex.time_zone(tz: str = '') → zoneinfo.ZoneInfo

Get a ZoneInfo object for the specified time zone.

The local time zone is determined from /etc/localtime; if that fails, UTC is assumed.

Parameters:

tz – Time zone string, like Europe/Berlin. An empty string means the local time zone.

Returns:

The ZoneInfo object.

Raises:

Error – If the time zone is invalid.

gws.lib.datetimex.to_basic_string(d: datetime.date | None = None, with_ms=False) → str

Convert a date to a compact string without separators.

Parameters:
  • d – Date to convert, the current date and time by default.

  • with_ms – Append milliseconds as three digits.

Returns:

A string like 20240501123000, or 20240501123000123 with milliseconds.

gws.lib.datetimex.to_iso_date_string(d: datetime.date | None = None) → str

Convert a date to an ISO date string.

Parameters:

d – Date to convert, the current date and time by default.

Returns:

A string like 2024-05-01.

gws.lib.datetimex.to_iso_string(d: datetime.date | None = None, with_tz='+', sep='T') → str

Convert a date or time to an ISO 8601 datetime string.

Parameters:
  • d – Date or time to convert, the current date and time by default.

  • with_tz – Time zone suffix: "+" for +hhmm, ":" for +hh:mm, "Z" for Z if the offset is zero and +hhmm otherwise. An empty value omits the time zone.

  • sep – Separator between date and time.

Returns:

A string like 2024-05-01T12:30:00+0200.

gws.lib.datetimex.to_iso_time_string(d: datetime.date | None = None, with_tz='+') → str

Convert a date to an ISO 8601 time string.

Parameters:
  • d – Date to convert, the current date and time by default.

  • with_tz – Time zone suffix: "+" for +hhmm, "Z" for Z if the offset is zero and +hhmm otherwise. An empty value omits the time zone.

Returns:

A string like 12:30:00+0200.

gws.lib.datetimex.to_local(d: datetime.date | None = None) → datetime.datetime

Convert a date to the local time zone.

Parameters:

d – Date to convert, the current date and time by default.

Returns:

A datetime in the local time zone.

gws.lib.datetimex.to_millis(d: datetime.date | None = None) → int

Convert a date to milliseconds since the Unix epoch.

Parameters:

d – Date to convert, the current date and time by default.

Returns:

Whole milliseconds since the epoch.

gws.lib.datetimex.to_string(fmt: str, d: datetime.date | None = None) → str

Convert a date to a string using a custom format.

Parameters:
  • fmt – strftime format string.

  • d – Date to convert, the current date and time by default.

Returns:

The formatted string.

gws.lib.datetimex.to_time_zone(tz: str, d: datetime.date | None = None) → datetime.datetime

Convert a date to a specific time zone.

Parameters:
  • tz – Target time zone string.

  • d – Date to convert, the current date and time by default.

Returns:

A datetime in the target time zone.

Raises:

Error – If the time zone is invalid.

gws.lib.datetimex.to_timestamp(d: datetime.date | None = None) → int

Convert a date to a Unix timestamp.

Parameters:

d – Date to convert, the current date and time by default.

Returns:

Whole seconds since the epoch.

gws.lib.datetimex.to_utc(d: datetime.date | None = None) → datetime.datetime

Convert a date to the UTC time zone.

Parameters:

d – Date to convert, the current date and time by default.

Returns:

A datetime in UTC.

gws.lib.datetimex.today(tz: str = '') → datetime.datetime

Get today’s date at midnight.

Parameters:

tz – Time zone string, the local time zone by default.

Returns:

A datetime at midnight of the current day in the given time zone.

gws.lib.datetimex.today_utc() → datetime.datetime

Get today’s date at midnight in UTC.

Returns:

A datetime at midnight of the current day in UTC.

gws.lib.datetimex.total_difference(d1: datetime.date, d2: datetime.date | None = None) → Diff

Compute the total difference between two dates in each unit.

Each component holds the whole difference expressed in that unit, for example, for a difference of one year and two months, years is 1 and months is 14.

Parameters:
  • d1 – The start date.

  • d2 – The end date, the current date and time by default.

Returns:

The difference from d1 to d2.

gws.lib.datetimex.UTC

The UTC time zone.

gws.lib.datetimex.week_of_month(d: datetime.date | None = None) → int
gws.lib.datetimex.week_of_year(d: datetime.date | None = None) → int