Formatting & Parsing
Pattern-based formatting, ISO parsing, type conversions, and range conversions. For arithmetic and anchoring, see the individual type pages.
Formatting
Format dates and times using pattern strings. Supported tokens:
| Token | Output | Example |
|---|---|---|
yyyy | 4-digit year | 2025 |
yy | 2-digit year | 25 |
MM | Zero-padded month | 03 |
MMM | Abbreviated month name | Mar |
dd | Zero-padded day | 05 |
HH | 24-hour hour | 14 |
mm | Minutes | 30 |
ss | Seconds | 05 |
SSS | Milliseconds | 042 |
Z | Timezone offset | +02:00 |
val zoned = instant.atZone(MpTimezone.of("Europe/Berlin"))
zoned.format("dd MMM yyyy") // "15 Mar 2025"
zoned.format("yyyy-MM-dd HH:mm:ss") // "2025-03-15 14:30:00"
zoned.format("dd/MM/yy") // "15/03/25"
zoned.format("HH:mm Z") // "14:30 +01:00" The formatter never throws exceptions. It handles malformed patterns gracefully — you'll get output, just
maybe not what you expected.
Parsing
All types support ISO-string parsing with both strict and safe variants:
// Strict — throws on invalid input
val instant = MpInstant.parse("2025-03-15T10:30:00Z")
val date = MpLocalDate.parse("2025-03-15")
val time = MpLocalTime.parse("14:30:00")
// Safe — returns null on invalid input
val maybe = MpLocalDate.tryParse("not-a-date") // null
val ok = MpLocalDate.tryParse("2025-03-15") // MpLocalDate
// Custom parser
val parser = MpDateTimeParser("dd/MM/yyyy")
val parsed = parser.parse("15/03/2025") Conversions
Move freely between types:
val instant = MpInstant.parse("2025-03-15T10:30:00Z")
// Instant -> Zoned
val zoned = instant.atZone(MpTimezone.of("Europe/Berlin"))
val utc = instant.atUTC()
// Instant -> Local (drops timezone info)
val localDate = instant.toLocalDate()
val localDateTime = instant.toLocalDateTime()
// Zoned -> Instant (recovers absolute time)
val backToInstant = zoned.toInstant()
// Local -> Instant (requires timezone)
val fromLocal = localDateTime.toInstant(MpTimezone.UTC)
// Epoch conversions
val millis = instant.toEpochMillis()
val seconds = instant.toEpochSeconds()
val fromMillis = MpInstant.fromEpochMillis(millis) Range conversions
Convert local date ranges to timezone-aware datetime ranges for different use cases:
import io.peekandpoke.ultra.datetime.DateTimeRangeConverter
val dateRange = MpLocalDateRange(
from = MpLocalDate.of(2025, 3, 15),
to = MpLocalDate.of(2025, 3, 20),
)
val tz = MpTimezone.of("Europe/Berlin")
// Noon to noon (hotel-style)
val noonToNoon = DateTimeRangeConverter.fromNoonToNoon(dateRange, tz)
// Morning to evening
val dayTime = DateTimeRangeConverter.fromMorningToEvening(dateRange, tz)
// Custom hour range
val custom = DateTimeRangeConverter.fromHourToHour(dateRange, tz, fromHour = 8, toHour = 18)