Skip to content

Date and Time Types

IsDatetime

IsDatetime(
    *,
    approx: Optional[datetime] = None,
    delta: Optional[Union[timedelta, int, float]] = None,
    gt: Optional[datetime] = None,
    lt: Optional[datetime] = None,
    ge: Optional[datetime] = None,
    le: Optional[datetime] = None,
    unix_number: bool = False,
    iso_string: bool = False,
    format_string: Optional[str] = None,
    enforce_tz: bool = True
)

Bases: IsNumeric[datetime]

Check if the value is a datetime, and matches the given conditions.

Parameters:

Name Type Description Default
approx Optional[datetime]

A value to approximately compare to.

None
delta Optional[Union[timedelta, int, float]]

The allowable different when comparing to the value to approx, if omitted 2 seconds is used, ints and floats are assumed to represent seconds and converted to timedeltas.

None
gt Optional[datetime]

Value which the compared value should be greater than (after).

None
lt Optional[datetime]

Value which the compared value should be less than (before).

None
ge Optional[datetime]

Value which the compared value should be greater than (after) or equal to.

None
le Optional[datetime]

Value which the compared value should be less than (before) or equal to.

None
unix_number bool

whether to allow unix timestamp numbers in comparison

False
iso_string bool

whether to allow iso formatted strings in comparison

False
format_string Optional[str]

if provided, format_string is used with datetime.strptime to parse strings

None
enforce_tz bool

whether timezone should be enforced in comparison, see below for more details

True

Examples of basic usage:

IsDatetime
from dirty_equals import IsDatetime
from datetime import datetime

y2k = datetime(2000, 1, 1)
assert datetime(2000, 1, 1) == IsDatetime(approx=y2k)
# Note: this requires the system timezone to be UTC
assert 946684800.123 == IsDatetime(approx=y2k, unix_number=True)
assert datetime(2000, 1, 1, 0, 0, 9) == IsDatetime(approx=y2k, delta=10)
assert '2000-01-01T00:00' == IsDatetime(approx=y2k, iso_string=True)

assert datetime(2000, 1, 2) == IsDatetime(gt=y2k)
assert datetime(1999, 1, 2) != IsDatetime(gt=y2k)

Timezones

Timezones are hard, anyone who claims otherwise is either a genius, a liar, or an idiot.

IsDatetime and its subtypes (e.g. IsNow) can be used in two modes, based on the enforce_tz parameter:

  • enforce_tz=True (the default):
    • if the datetime wrapped by IsDatetime is timezone naive, the compared value must also be timezone naive.
    • if the datetime wrapped by IsDatetime has a timezone, the compared value must have a timezone with the same offset.
  • enforce_tz=False:
    • if the datetime wrapped by IsDatetime is timezone naive, the compared value can either be naive or have a timezone all that matters is the datetime values match.
    • if the datetime wrapped by IsDatetime has a timezone, the compared value needs to represent the same point in time - either way it must have a timezone.

Example

IsDatetime & timezones
from datetime import datetime

from dirty_equals import IsDatetime
import pytz

tz_london = pytz.timezone('Europe/London')
new_year_london = tz_london.localize(datetime(2000, 1, 1))

tz_nyc = pytz.timezone('America/New_York')
new_year_eve_nyc = tz_nyc.localize(datetime(1999, 12, 31, 19, 0, 0))

assert new_year_eve_nyc == IsDatetime(approx=new_year_london, enforce_tz=False)
assert new_year_eve_nyc != IsDatetime(approx=new_year_london, enforce_tz=True)

new_year_naive = datetime(2000, 1, 1)

assert new_year_naive != IsDatetime(approx=new_year_london, enforce_tz=False)
assert new_year_naive != IsDatetime(approx=new_year_eve_nyc, enforce_tz=False)
assert new_year_london == IsDatetime(approx=new_year_naive, enforce_tz=False)
assert new_year_eve_nyc != IsDatetime(approx=new_year_naive, enforce_tz=False)

IsNow

IsNow(
    *,
    delta: Union[timedelta, int, float] = 2,
    unix_number: bool = False,
    iso_string: bool = False,
    format_string: Optional[str] = None,
    enforce_tz: bool = True,
    tz: Union[None, str, tzinfo] = None
)

Bases: IsDatetime

Check if a datetime is close to now, this is similar to IsDatetime(approx=datetime.now()), but slightly more powerful.

Parameters:

Name Type Description Default
delta Union[timedelta, int, float]

The allowable different when comparing to the value to now, if omitted 2 seconds is used, ints and floats are assumed to represent seconds and converted to timedeltas.

2
unix_number bool

whether to allow unix timestamp numbers in comparison

False
iso_string bool

whether to allow iso formatted strings in comparison

False
format_string Optional[str]

if provided, format_string is used with datetime.strptime to parse strings

None
enforce_tz bool

whether timezone should be enforced in comparison, see below for more details

True
tz Union[None, str, tzinfo]

either a pytz.timezone, a datetime.timezone or a string which will be passed to pytz.timezone, if provided now will be converted to this timezone.

None
IsNow
from dirty_equals import IsNow
from datetime import datetime, timezone

now = datetime.now()
assert now == IsNow
assert now.timestamp() == IsNow(unix_number=True)
assert now.timestamp() != IsNow
assert now.isoformat() == IsNow(iso_string=True)
assert now.isoformat() != IsNow

utc_now = datetime.utcnow().replace(tzinfo=timezone.utc)
assert utc_now == IsNow(tz=timezone.utc)

IsDate

IsDate(
    *,
    approx: Optional[date] = None,
    delta: Optional[Union[timedelta, int, float]] = None,
    gt: Optional[date] = None,
    lt: Optional[date] = None,
    ge: Optional[date] = None,
    le: Optional[date] = None,
    iso_string: bool = False,
    format_string: Optional[str] = None
)

Bases: IsNumeric[date]

Check if the value is a date, and matches the given conditions.

Parameters:

Name Type Description Default
approx Optional[date]

A value to approximately compare to.

None
delta Optional[Union[timedelta, int, float]]

The allowable different when comparing to the value to now, if omitted 2 seconds is used, ints and floats are assumed to represent seconds and converted to timedeltas.

None
gt Optional[date]

Value which the compared value should be greater than (after).

None
lt Optional[date]

Value which the compared value should be less than (before).

None
ge Optional[date]

Value which the compared value should be greater than (after) or equal to.

None
le Optional[date]

Value which the compared value should be less than (before) or equal to.

None
iso_string bool

whether to allow iso formatted strings in comparison

False
format_string Optional[str]

if provided, format_string is used with datetime.strptime to parse strings

None

Examples of basic usage:

IsDate
from dirty_equals import IsDate
from datetime import date

y2k = date(2000, 1, 1)
assert date(2000, 1, 1) == IsDate(approx=y2k)
assert '2000-01-01' == IsDate(approx=y2k, iso_string=True)

assert date(2000, 1, 2) == IsDate(gt=y2k)
assert date(1999, 1, 2) != IsDate(gt=y2k)

IsToday

IsToday(
    *,
    iso_string: bool = False,
    format_string: Optional[str] = None
)

Bases: IsDate

Check if a date is today, this is similar to IsDate(approx=date.today()), but slightly more powerful.

Parameters:

Name Type Description Default
iso_string bool

whether to allow iso formatted strings in comparison

False
format_string Optional[str]

if provided, format_string is used with datetime.strptime to parse strings

None
IsToday
from dirty_equals import IsToday
from datetime import date, timedelta

today = date.today()
assert today == IsToday
assert today.isoformat() == IsToday(iso_string=True)
assert today.isoformat() != IsToday
assert today + timedelta(days=1) != IsToday
assert today.strftime('%Y/%m/%d') == IsToday(format_string='%Y/%m/%d')
assert today.strftime('%Y/%m/%d') != IsToday()