Date Time Period
A difference between two instants, decomposed into date and time components.
The date components are: years (DateTimeUnit.YEAR), months (DateTimeUnit.MONTH), and days (DateTimeUnit.DAY).
The time components are: hours (DateTimeUnit.HOUR), minutes (DateTimeUnit.MINUTE), seconds (DateTimeUnit.SECOND), and nanoseconds (DateTimeUnit.NANOSECOND).
The time components are not independent and are always normalized together. Likewise, months are normalized together with years. For example, there is no difference between DateTimePeriod(months = 24, hours = 2, minutes = 63)
and DateTimePeriod(years = 2, hours = 3, minutes = 3)
.
All components can also be negative: for example, DateTimePeriod(months = -5, days = 6, hours = -3)
. Whereas months = 5
means "5 months after," months = -5
means "5 months earlier."
A constant time interval that consists of a single non-zero component (like "yearly" or "quarterly") should be represented by a DateTimeUnit directly instead of a DateTimePeriod: for example, instead of DateTimePeriod(months = 6)
, one could use DateTimeUnit.MONTH * 6
. This provides a wider variety of operations: for example, finding how many such intervals fit between two instants or dates or adding a multiple of such intervals at once.
Interaction with other entities
DateTimePeriod can be returned from Instant.periodUntil, representing the difference between two instants. Conversely, there is an Instant.plus overload that accepts a DateTimePeriod and returns a new instant.
DatePeriod is a subtype of DateTimePeriod that only stores the date components and has all time components equal to zero.
DateTimePeriod can be thought of as a combination of a Duration and a DatePeriod, as it contains both the time components of Duration and the date components of DatePeriod. Duration.toDateTimePeriod can be used to convert a Duration to the corresponding DateTimePeriod.
Construction, serialization, and deserialization
When a DateTimePeriod is constructed in any way, a DatePeriod value, which is a subtype of DateTimePeriod, will be returned if all time components happen to be zero.
A DateTimePeriod
can be constructed using the constructor function with the same name. See sample 1.
parse and toString methods can be used to obtain a DateTimePeriod from and convert it to a string in the ISO 8601 extended format. See sample 2.
DateTimePeriod
can also be returned as the result of instant arithmetic operations (see Instant.periodUntil).
Additionally, there are several kotlinx-serialization
serializers for DateTimePeriod:
DateTimePeriodIso8601Serializer for the ISO 8601 format;
DateTimePeriodComponentSerializer for an object with components.
Samples
import kotlinx.datetime.*
import kotlin.test.*
import kotlin.time.Duration.Companion.days
import kotlin.time.Duration.Companion.minutes
fun main() {
//sampleStart
// Constructing a DateTimePeriod using its constructor function
val period = DateTimePeriod(years = 5, months = 21, days = 36, seconds = 3601)
check(period.years == 6) // 5 years + (21 months / 12)
check(period.months == 9) // 21 months % 12
check(period.days == 36)
check(period.hours == 1) // 3601 seconds / 3600
check(period.minutes == 0)
check(period.seconds == 1)
check(period.nanoseconds == 0)
check(DateTimePeriod(months = -24) as DatePeriod == DatePeriod(years = -2))
//sampleEnd
}
import kotlinx.datetime.*
import kotlin.test.*
import kotlin.time.Duration.Companion.days
import kotlin.time.Duration.Companion.minutes
fun main() {
//sampleStart
// Parsing and formatting a DateTimePeriod
val string = "P-2M-3DT-4H60M"
val period = DateTimePeriod.parse(string)
check(period.toString() == "-P2M3DT3H")
//sampleEnd
}