optional

fun <T : DateTimeFormatBuilder> T.optional(ifZero: String = "", format: T.() -> Unit)(source)

An optional section.

When formatting, the section is formatted if the value of any field in the block is not equal to the default value. Only optional calls where all the fields have default values are permitted. See alternativeParsing to parse some fields optionally without introducing a particular formatting behavior.

Example:

offsetHours(); char(':'); offsetMinutesOfHour()
optional { char(':'); offsetSecondsOfMinute() }

Here, because seconds have the default value of zero, they are formatted only if they are not equal to zero, so the UTC offset +18:30:00 gets formatted as "+18:30", but +18:30:01 becomes "+18:30:01".

When parsing, either format or, if that fails, the literal ifZero are parsed. If the ifZero string is parsed, the values in format get assigned their default values.

ifZero defines the string that is used if values are the default ones.

Throws

if not all fields used in format have a default value.

Samples

import kotlinx.datetime.*
import kotlinx.datetime.format.*
import kotlin.test.*

fun main() { 
   //sampleStart 
   // Defining a custom format that includes parts that will be omitted if they are zero
val format = UtcOffset.Format {
    optional(ifZero = "Z") {
        offsetHours()
        optional {
            char(':')
            offsetMinutesOfHour()
            optional {
                char(':')
                offsetSecondsOfMinute()
            }
        }
    }
}
// During parsing, the optional parts can be omitted:
check(format.parse("Z") == UtcOffset.ZERO)
check(format.parse("-05") == UtcOffset(hours = -5))
check(format.parse("-05:30") == UtcOffset(hours = -5, minutes = -30))
check(format.parse("-05:15:05") == UtcOffset(hours = -5, minutes = -15, seconds = -5))
// ... but they can also be present:
check(format.parse("-05:00") == UtcOffset(hours = -5))
check(format.parse("-05:00:00") == UtcOffset(hours = -5))
// During formatting, the optional parts are only included if they are non-zero:
check(UtcOffset.ZERO.format(format) == "Z")
check(UtcOffset(hours = -5).format(format) == "-05")
check(UtcOffset(hours = -5, minutes = -30).format(format) == "-05:30")
check(UtcOffset(hours = -5, minutes = -15, seconds = -5).format(format) == "-05:15:05")

try {
    LocalDate.Format { optional { year() }}
    fail("Expected IllegalArgumentException")
} catch (e: IllegalArgumentException) {
    // Since `year` has no optional component, it is an error to put it inside `optional`.
    // Use `alternativeParsing` for parsing-only optional components.
} 
   //sampleEnd
}