by Unicode Pattern
Appends a Unicode datetime format string to the DateTimeFormatBuilder.
This is the format string syntax used by the Java Time's DateTimeFormatter
class, Swift's and Objective-C's NSDateFormatter
class, and the ICU library. The syntax is specified at https://unicode-org.github.io/icu/userguide/format_parse/datetime/#datetime-format-syntax.
Currently, locale-aware directives are not supported, due to no locale support in Kotlin.
In addition to the standard syntax, this function also supports the following extensions:
[]
denote optional sections. For example,hh:mm[:ss]
will allow parsing seconds optionally. This is similar to what is supported by the Java Time'sDateTimeFormatter
class.
Usage example:
DateTimeComponents.Format {
// 2023-01-20T23:53:16.312+03:30[Asia/Tehran]
byUnicodePattern("uuuu-MM-dd'T'HH:mm[:ss[.SSS]]xxxxx'['VV']'")
}
The list of supported directives is as follows:
Directive | Meaning |
---|---|
'string' | literal string , without quotes |
''' | literal char ' |
[fmt] | equivalent to fmt during formatting, but during parsing also accepts the empty string |
u | ISO year without padding |
uu | last two digits of the ISO year, with the base year 2000 |
uuuu | ISO year, zero-padded to four digits |
M , L | month number (1-12), without padding |
MM , LL | month number (01-12), zero-padded to two digits |
d | day-of-month (1-31), without padding |
H | hour-of-day (0-23), without padding |
HH | hour-of-day (00-23), zero-padded to two digits |
m | minute-of-hour (0-59), without padding |
mm | minute-of-hour (00-59), zero-padded to two digits |
s | second-of-hour (0-59), without padding |
ss | second-of-hour (00-59), zero-padded to two digits |
S , SS , SSS ... | fraction-of-second without a leading dot, with as many digits as the format length |
VV | timezone name (for example, Europe/Berlin ) |
The UTC offset is formatted using one of the following directives. In every one of these formats, hours, minutes, and seconds are zero-padded to two digits. Also, hours are unconditionally present.
Directive | Minutes | Seconds | Separator | Representation of zero |
---|---|---|---|---|
X | unless zero | never | none | Z |
XX | always | never | none | Z |
XXX | always | never | colon | Z |
XXXX | always | unless zero | none | Z |
XXXXX , ZZZZZ | always | unless zero | colon | Z |
x | unless zero | never | none | +00 |
xx , Z , ZZ , ZZZ | always | never | none | +0000 |
xxx | always | never | colon | +00:00 |
xxxx | always | unless zero | none | +0000 |
xxxxx | always | unless zero | colon | +00:00 |
Additionally, because the y
directive is very often used instead of u
, they are taken to mean the same. This may lead to unexpected results if the year is negative: y
would always produce a positive number, whereas u
may sometimes produce a negative one. For example:
LocalDate(-10, 1, 5).format { byUnicodeFormat("yyyy-MM-dd") } // -0010-01-05
LocalDate(-10, 1, 5).toJavaLocalDate().format(java.time.format.DateTimeFormatter.ofPattern("yyyy-MM-dd")) // 0011-01-05
Note that, when the format includes the era directive, byUnicodePattern will fail with an exception, so almost all of the intentional usages of y
will correctly report an error instead of behaving slightly differently.
Throws
if the builder is incompatible with the specified directives.
if the kotlinx-datetime library does not support the specified directives.
Samples
import kotlinx.datetime.*
import kotlinx.datetime.format.*
import kotlin.test.*
fun main() {
//sampleStart
// Using the Unicode pattern to define a custom format and obtain the corresponding Kotlin code
val customFormat = LocalDate.Format {
@OptIn(FormatStringsInDatetimeFormats::class)
byUnicodePattern("MM/dd uuuu")
}
check(customFormat.format(LocalDate(2021, 1, 13)) == "01/13 2021")
check(
DateTimeFormat.formatAsKotlinBuilderDsl(customFormat) == """
monthNumber()
char('/')
dayOfMonth()
char(' ')
year()
""".trimIndent()
)
//sampleEnd
}