Some data is static - it rarely or never changes. Other data changes over time, and you need to preserve a history of those changes so that calculations run against past dates use the values that were correct at that time.
The platform provides two reusable design patterns for handling time-based data, both using FROM_DATE and TO_DATE attributes.
Why This Matters
Consider an object that stores configuration settings for an entity - for example, an allocation method or a rate. If you store only a single value and that value changes, you lose the historical record. Any process that runs against a past date will use the current value instead of the one that was valid at that time.
The solution is not to overwrite values or duplicate the parent entity. Instead, you create a separate date-ranged child object that stores each version of the setting with the dates it was valid.
Pattern 1 - Periodic Validity
Use this pattern when a setting can change over time and you need to preserve historical accuracy.
A date-ranged object contains:
a reference to the parent entity
the value being stored
a
FROM_DATEindicating when the record became valida
TO_DATEindicating when it ceased to be valid (optional - if empty, the record is treated as open-ended)
Multiple records can exist for the same entity, each covering a different time period. When a value changes, the previous record is end-dated and a new record is created with the updated value and a new FROM_DATE.
FROM_DATE must be part of the unique key on a periodic validity object. This is what allows multiple records to exist for the same entity without violating uniqueness.
Filtering by effective date
To retrieve the record that was valid on a given date, use the effective operator on FROM_DATE in a filter. This returns the latest record whose FROM_DATE is on or before the specified date. If TO_DATE is used, the filter should also check that the query date falls on or before TO_DATE, or that TO_DATE is empty.
Because FROM_DATE and TO_DATE are standard attribute names used consistently across all date-ranged objects, the same filter logic can be reused across multiple objects.
Why not add date ranges to the parent object?
You might consider creating a new parent record each time a setting changes. The problem is that the parent entity's unique key must remain stable - other records reference it, and changing or duplicating it fragments history. A date-ranged child object keeps the parent identity intact while preserving a full history of changing settings.
Pattern 2 - Lifetime Validity
Use this pattern for entities that exist for a defined period but do not change their settings over time.
In this case:
FROM_DATEindicates when the entity became activeTO_DATEindicates when it ceased to be active (if applicable)there is only one record per entity
FROM_DATEis not part of the unique key
If TO_DATE is empty, the entity is still active.
This pattern is simpler than periodic validity and is appropriate when you only need to know whether an entity was active on a given date, not track changes to its attributes over time.
Naming Conventions
Always use FROM_DATE and TO_DATE as the attribute System Names for validity period attributes. These names are recognised by the platform's Virtual Object publication logic and enable filter reuse across objects. Using different names will cause date logic in Virtual Objects to behave unexpectedly.
For more on how Virtual Objects interpret these date patterns, see Virtual Objects.
Choosing the Right Pattern
Use periodic validity when a setting can change and you need historical accuracy - for example, rates, methods, or parameters that are updated periodically.
Use lifetime validity when you simply need to record when an entity was active - for example, a contract with a start and end date that does not otherwise change.
