diff --git a/docs/time.md b/docs/time.md index 4337052..aba9860 100644 --- a/docs/time.md +++ b/docs/time.md @@ -21,7 +21,11 @@ Represent some moment of time not depending on the calendar. It is similar to `T val t2 = Instant(1704110400) // 2024-01-01T12:00:00Z // from RFC3339 string: - val t3 = Instant("2024-01-01T12:00:00Z") + val t3 = Instant("2024-01-01T12:00:00.123456Z") + + // truncation: + val t4 = t3.truncateToMinute + assertEquals(t4.toRFC3339(), "2024-01-01T12:00:00Z") // to localized DateTime (uses system default TZ if not specified): val dt = t3.toDateTime("+02:00") @@ -36,15 +40,17 @@ Represent some moment of time not depending on the calendar. It is similar to `T | nanosecondsOfSecond: Int | offset from epochWholeSeconds in nanos | | isDistantFuture: Bool | true if it `Instant.distantFuture` | | isDistantPast: Bool | true if it `Instant.distantPast` | -| truncateToSecond: Instant | create new instance truncated to second | -| truncateToMillisecond: Instant | truncate new instance to millisecond | +| truncateToMinute: Instant | create new instance truncated to minute | +| truncateToSecond: Instant | create new instance truncated to second | +| truncateToMillisecond: Instant | truncate new instance to millisecond | | truncateToMicrosecond: Instant | truncate new instance to microsecond | | toRFC3339(): String | format as RFC3339 string (UTC) | | toDateTime(tz?): DateTime | localize to a TimeZone (ID string or offset seconds) | ## Calendar time: `DateTime` -`DateTime` represents a point in time in a specific timezone. It provides access to calendar components like year, month, and day. +`DateTime` represents a point in time in a specific timezone. It provides access to calendar components like year, +month, and day. ### Constructing @@ -67,24 +73,24 @@ Represent some moment of time not depending on the calendar. It is similar to `T ### DateTime members -| member | description | -|-------------------|------------------------------------------------------| -| year: Int | year component | -| month: Int | month component (1..12) | -| day: Int | day of month (alias `dayOfMonth`) | -| hour: Int | hour component (0..23) | -| minute: Int | minute component (0..59) | -| second: Int | second component (0..59) | -| dayOfWeek: Int | day of week (1=Monday, 7=Sunday) | -| timeZone: String | timezone ID string | -| toInstant(): Instant | convert back to absolute Instant | -| toUTC(): DateTime | shortcut to convert to UTC | -| toTimeZone(tz): DateTime | convert to another timezone | -| addMonths(n): DateTime | add/subtract months (normalizes end of month) | -| addYears(n): DateTime | add/subtract years | -| toRFC3339(): String | format with timezone offset | -| static now(tz?): DateTime | create DateTime with current time | -| static parseRFC3339(s): DateTime | parse RFC3339 string | +| member | description | +|----------------------------------|-----------------------------------------------| +| year: Int | year component | +| month: Int | month component (1..12) | +| day: Int | day of month (alias `dayOfMonth`) | +| hour: Int | hour component (0..23) | +| minute: Int | minute component (0..59) | +| second: Int | second component (0..59) | +| dayOfWeek: Int | day of week (1=Monday, 7=Sunday) | +| timeZone: String | timezone ID string | +| toInstant(): Instant | convert back to absolute Instant | +| toUTC(): DateTime | shortcut to convert to UTC | +| toTimeZone(tz): DateTime | convert to another timezone | +| addMonths(n): DateTime | add/subtract months (normalizes end of month) | +| addYears(n): DateTime | add/subtract years | +| toRFC3339(): String | format with timezone offset | +| static now(tz?): DateTime | create DateTime with current time | +| static parseRFC3339(s): DateTime | parse RFC3339 string | ### Arithmetic and normalization diff --git a/lynglib/src/commonMain/kotlin/net/sergeych/lyng/obj/ObjInstant.kt b/lynglib/src/commonMain/kotlin/net/sergeych/lyng/obj/ObjInstant.kt index 23d3ffc..ed50dfc 100644 --- a/lynglib/src/commonMain/kotlin/net/sergeych/lyng/obj/ObjInstant.kt +++ b/lynglib/src/commonMain/kotlin/net/sergeych/lyng/obj/ObjInstant.kt @@ -17,10 +17,7 @@ package net.sergeych.lyng.obj -import kotlinx.datetime.Instant -import kotlinx.datetime.TimeZone -import kotlinx.datetime.UtcOffset -import kotlinx.datetime.asTimeZone +import kotlinx.datetime.* import kotlinx.serialization.json.JsonElement import kotlinx.serialization.json.JsonPrimitive import net.sergeych.lyng.Scope @@ -193,6 +190,18 @@ class ObjInstant(val instant: Instant,val truncateMode: LynonSettings.InstantTru moduleName = "lyng.time", getter = { ObjInt(thisAs().instant.nanosecondsOfSecond.toLong()) } ) + addFnDoc( + name = "truncateToMinute", + doc = "Truncate this instant to the nearest minute.", + returns = type("lyng.Instant"), + moduleName = "lyng.time" + ) { + val t = thisAs().instant + val tz = TimeZone.UTC + val dt = t.toLocalDateTime(tz) + val truncated = LocalDateTime(dt.year, dt.month, dt.dayOfMonth, dt.hour, dt.minute, 0, 0) + ObjInstant(truncated.toInstant(tz), LynonSettings.InstantTruncateMode.Second) + } addFnDoc( name = "truncateToSecond", doc = "Truncate this instant to the nearest second.", diff --git a/lynglib/src/commonTest/kotlin/ScriptTest.kt b/lynglib/src/commonTest/kotlin/ScriptTest.kt index bcc7fc6..80a05fe 100644 --- a/lynglib/src/commonTest/kotlin/ScriptTest.kt +++ b/lynglib/src/commonTest/kotlin/ScriptTest.kt @@ -3169,6 +3169,19 @@ class ScriptTest { assertEquals( n1 - now, 7.seconds ) assertEquals( now - n1, -7.seconds ) + val t3 = Instant("2024-01-01T12:00:00.123456Z") + val t4 = t3.truncateToMinute + assertEquals(t4.toRFC3339(), "2024-01-01T12:00:00Z") + assertEquals( + "2024-01-01T12:00:00Z", + Instant("2024-01-01T12:00:59.999Z").truncateToMinute().toRFC3339() + ) + + val t5 = t3.truncateToSecond + assertEquals(t5.toRFC3339(), "2024-01-01T12:00:00Z") + + val t6 = t3.truncateToMillisecond + assertEquals(t6.toRFC3339(), "2024-01-01T12:00:00.123Z") """.trimIndent() ) delay(1000)