Skip to content

relationalai.std.dates.date_subtract()

date_subtract(
date: date|datetime|Producer,
period: Producer
) -> Expression

Subtracts a time period from a date or datetime value. Same as using the - operator with a period constructor. That is, date_subtract(date, period) is equivalent to date - period. If date or period is a Producer, then date_subtract() also acts as a filter and removes invalid values from the producer. In particular, if period is sub-day, then any date values produced by date are filtered out and the subtraction is only performed on datetime values. Must be called in a rule or query context.

NameTypeDescription
dateProducer or Python date or datetimeThe date or datetime value from which to subtract the period.
periodProducerThe time period to subtract from the date. May be one of:

An Expression object. If date is a date value and period is one of years(), months(), or days(), then the Expression produces date values. If date is a datetime value, then the Expression produces datetime values.

You can use date_subtract() to subtract a time period from a date or datetime value. Typically, however, you use the - operator instead of calling date_subtract() directly:

import relationalai as rai
from relationalai.std import alias, dates
# =====
# SETUP
# =====
model = rai.Model("MyModel")
Event = model.Type("Event")
with model.rule():
Event.add(id=1).set(end=dates.datetime(2021, 1, 1, 9, 30), duration=dates.hours(1))
Event.add(id=2).set(end=dates.date(2021, 2, 1), duration=dates.days(1))
Event.add(id=3).set(end=dates.date(2021, 3, 1), duration=dates.hours(1))
# =======
# EXAMPLE
# =======
with model.rule():
event = Event()
# date_subtract() filters out any events with invalid start or duration values.
# Event 3 has a date start value and a sub-day duration, so the following
# only sets the start property for Events 1 and 2.
event.set(start=event.end - event.duration)
# Since Event 3 is filtered above, the following only sets the
# has_valid_end_and_duration property for Events 1 and 2.
event.set(has_valid_end_and_duration=True)
with model.query() as select:
event = Event()
response = select(event.id, event.start, event.has_valid_end_and_duration)
print(response.results)
# id start has_valid_end_and_duration
# 0 1 2021-01-01 08:30:00 True
# 1 2 2021-01-31 00:00:00 True
# 2 3 NaT NaN

If you need to subtract a sub-day time period from a date, you can use datetime.fromdate() to convert the date to a datetime value before subtracting the period:

# Alternative version of the rule in the preceding example that converts any date
# values produced by event.end to datetime values before subtracting the duration.
with model.rule():
event = Event()
with model.match():
# If event.start is a date, convert it to a datetime before subtracting the duration.
with model.case():
dates.Date(event.end)
date_as_time = dates.datetime.fromdate(event.end)
event.set(end=date_as_time - event.duration)
# Otherwise, subtract the duration without conversion.
with model.case():
event.set(end=event.end - event.duration)
with model.query() as select:
event = Event()
response = select(event.id, event.start)
print(response.results)
# id start
# 0 1 2021-01-01 08:30:00
# 1 2 2021-01-31 00:00:00
# 2 3 2021-02-28 23:00:00