Giter Site home page Giter Site logo

kotlinx-datetime's Introduction

kotlinx-datetime

Kotlin Alpha JetBrains official project GitHub license Maven Central Kotlin KDoc link Slack channel TeamCity build

A multiplatform Kotlin library for working with date and time.

See Using in your projects for the instructions how to setup a dependency in your project.

Design overview

There are a few guiding principles in the design of kotlinx-datetime. First of all, it is pragmatic, focused on the most common problems developers face every day (pun intended) when working with dates and times. It is not all-encompassing and lacks some domain-specific utilities that special-purpose applications might need. We chose convenience over generality, so the API surface this library provides is as minimal as possible to meet the use-cases.

The library puts a clear boundary between the physical time of an instant and the local, time-zone dependent civil time, consisting of components such as year, month, etc that people use when talking about time. We intentionally avoid entities in the library that mix both together and could be misused. However, there are convenience operations that take, for example, a physical instant and perform a calendar-based adjustment (such as adding a month); all such operations explicitly take a time-zone information as parameter to clearly state that their result depends on the civil time-zone rules which are subject to change at any time.

The library is based on the ISO 8601 international standard, other ways to represent dates and times are out of its scope. Internationalization (such as locale-specific month and day names) is out the scope, too.

Types

The library provides a basic set of types for working with date and time:

  • Instant to represent a moment on the UTC-SLS time scale;
  • Clock to obtain the current instant;
  • LocalDateTime to represent date and time components without a reference to the particular time zone;
  • LocalDate to represent the components of date only;
  • LocalTime to represent the components of time only;
  • TimeZone and FixedOffsetTimeZone provide time zone information to convert between Instant and LocalDateTime;
  • Month and DayOfWeek enums;
  • DateTimePeriod to represent a difference between two instants decomposed into date and time units;
  • DatePeriod is a subclass of DateTimePeriod with zero time components, it represents a difference between two LocalDate values decomposed into date units.
  • DateTimeUnit provides a set of predefined date and time units to use in arithmetic operations on Instant and LocalDate.
  • UtcOffset represents the amount of time the local date/time at a particular time zone differs from the date/time at UTC.

Type use-cases

Here is some basic advice on how to choose which of the date-carrying types to use in what cases:

  • Use Instant to represent a timestamp of the event that had already happened in the past (like a timestamp of a log entry) or will definitely happen in a well-defined instant of time in the future not far away from now (like an order confirmation deadline in 1 hour from now).

  • Use LocalDateTime to represent a time of the event that is scheduled to happen in the far future at a certain local time (like a scheduled meeting in a few months from now). You'll have to keep track of the TimeZone of the scheduled event separately. Try to avoid converting future events to Instant in advance, because time-zone rules might change unexpectedly in the future. In this blog post, you can read more about why it's not always a good idea to use Instant everywhere.

    Also, use LocalDateTime to decode an Instant to its local date-time components for display and UIs.

  • Use LocalDate to represent the date of an event that does not have a specific time associated with it (like a birth date).

  • Use LocalTime to represent the time of an event that does not have a specific date associated with it.

Operations

With the above types you can get the following operations done.

Getting the current moment of time

The current moment of time can be captured with the Instant type. To obtain an Instant corresponding to the current moment of time, use now() function of the Clock interface:

val clock: Clock = ...
val currentMoment = clock.now()

An instance of Clock can be injected through the function/class parameters, or you can use its default implementation Clock.System that represents the system clock:

val currentMoment = Clock.System.now()

Converting an instant to local date and time components

An Instant is just a counter of high resolution time intervals since the beginning of time scale. To get human readable components from an Instant value, you need to convert it to the LocalDateTime type that represents date and time components without a reference to the particular time zone.

The TimeZone type provides the rules to convert instants from and to date/time components.

val currentMoment: Instant = Clock.System.now()
val datetimeInUtc: LocalDateTime = currentMoment.toLocalDateTime(TimeZone.UTC)
val datetimeInSystemZone: LocalDateTime = currentMoment.toLocalDateTime(TimeZone.currentSystemDefault())

A LocalDateTime instance exposes familiar components of the Gregorian calendar: year, month, dayOfMonth, hour, and so on up to nanosecond. The property dayOfWeek shows what weekday that date is, and dayOfYear shows the day number since the beginning of a year.

Additional time zones can be acquired by their string identifier with the TimeZone.of(id: String) function.

val tzBerlin = TimeZone.of("Europe/Berlin")
val datetimeInBerlin = currentMoment.toLocalDateTime(tzBerlin)

A LocalDateTime instance can be constructed from individual components:

val kotlinReleaseDateTime = LocalDateTime(2016, 2, 15, 16, 57, 0, 0)

An instant can be obtained from LocalDateTime by interpreting it as a time moment in a particular TimeZone:

val kotlinReleaseInstant = kotlinReleaseDateTime.toInstant(TimeZone.of("UTC+3"))

Getting local date components

A LocalDate represents a local date without time. You can obtain one from an Instant by converting it to LocalDateTime and taking its date property.

val now: Instant = Clock.System.now()
val today: LocalDate = now.toLocalDateTime(TimeZone.currentSystemDefault()).date
// or shorter
val today: LocalDate = Clock.System.todayIn(TimeZone.currentSystemDefault())

Note, that today's date really depends on the time zone in which you're observing the current moment.

LocalDate can be constructed from three components, year, month, and day:

val knownDate = LocalDate(2020, 2, 21)

Getting local time components

A LocalTime represents local time without date. You can obtain one from an Instant by converting it to LocalDateTime and taking its time property.

val now: Instant = Clock.System.now()
val thisTime: LocalTime = now.toLocalDateTime(TimeZone.currentSystemDefault()).time

A LocalTime can be constructed from four components, hour, minute, second and nanosecond:

val knownTime = LocalTime(hour = 23, minute = 59, second = 12)
val timeWithNanos = LocalTime(hour = 23, minute = 59, second = 12, nanosecond = 999)
val hourMinute = LocalTime(hour = 12, minute = 13)

Converting instant to and from unix time

An Instant can be converted to a number of milliseconds since the Unix/POSIX epoch with the toEpochMilliseconds() function. To convert back, use the companion object function Instant.fromEpochMilliseconds(Long).

Converting instant and local date/time to and from the ISO 8601 string

Instant, LocalDateTime, LocalDate and LocalTime provide shortcuts for parsing and formatting them using the extended ISO-8601 format. The toString() function is used to convert the value to a string in that format, and the parse function in companion object is used to parse a string representation back.

val instantNow = Clock.System.now()
instantNow.toString()  // returns something like 2015-12-31T12:30:00Z
val instantBefore = Instant.parse("2010-06-01T22:19:44.475Z")

LocalDateTime uses a similar format, but without Z UTC time zone designator in the end.

LocalDate uses a format with just year, month, and date components, e.g. 2010-06-01.

LocalTime uses a format with just hour, minute, second and (if non-zero) nanosecond components, e.g. 12:01:03.

LocalDateTime.parse("2010-06-01T22:19:44")
LocalDate.parse("2010-06-01")
LocalTime.parse("12:01:03")
LocalTime.parse("12:00:03.999")
LocalTime.parse("12:0:03.999") // fails with an IllegalArgumentException

Working with other string formats

When some data needs to be formatted in some format other than ISO-8601, one can define their own format or use some of the predefined ones:

// import kotlinx.datetime.format.*

val dateFormat = LocalDate.Format {
    monthNumber(padding = Padding.SPACE)
    char('/')
    dayOfMonth()
    char(' ')
    year()
}

val date = dateFormat.parse("12/24 2023")
println(date.format(LocalDate.Formats.ISO_BASIC)) // "20231224"

Using Unicode format strings (like yyyy-MM-dd)

Given a constant format string like the ones used by Java's DateTimeFormatter.ofPattern can be converted to Kotlin code using the following invocation:

// import kotlinx.datetime.format.*

println(DateTimeFormat.formatAsKotlinBuilderDsl(DateTimeComponents.Format {
    byUnicodePattern("uuuu-MM-dd'T'HH:mm:ss[.SSS]Z")
}))

// will print:
/*
date(LocalDate.Formats.ISO)
char('T')
hour()
char(':')
minute()
char(':')
second()
alternativeParsing({
}) {
    char('.')
    secondFraction(3)
}
offset(UtcOffset.Formats.FOUR_DIGITS)
 */

When your format string is not constant, with the FormatStringsInDatetimeFormats opt-in, you can use the format without converting it to Kotlin code beforehand:

val formatPattern = "yyyy-MM-dd'T'HH:mm:ss[.SSS]"

@OptIn(FormatStringsInDatetimeFormats::class)
val dateTimeFormat = LocalDateTime.Format {
    byUnicodePattern(formatPattern)
}

dateTimeFormat.parse("2023-12-24T23:59:59")

Parsing and formatting partial, compound or out-of-bounds data

Sometimes, the required string format doesn't fully correspond to any of the classes kotlinx-datetime provides. In these cases, DateTimeComponents, a collection of all date-time fields, can be used instead.

// import kotlinx.datetime.format.*

val yearMonth = DateTimeComponents.Format { year(); char('-'); monthNumber() }
    .parse("2024-01")
println(yearMonth.year)
println(yearMonth.monthNumber)

val dateTimeOffset = DateTimeComponents.Formats.ISO_DATE_TIME_OFFSET
    .parse("2023-01-07T23:16:15.53+02:00")
println(dateTimeOffset.toUtcOffset()) // +02:00
println(dateTimeOffset.toLocalDateTime()) // 2023-01-07T23:16:15.53

Occasionally, one can encounter strings where the values are slightly off: for example, 23:59:60, where 60 is an invalid value for the second. DateTimeComponents allows parsing such values as well and then mutating them before conversion.

val time = DateTimeComponents.Format { time(LocalTime.Formats.ISO) }
    .parse("23:59:60").apply {
        if (second == 60) second = 59
    }.toLocalTime()
println(time) // 23:59:59

Because DateTimeComponents is provided specifically for parsing and formatting, there is no way to construct it normally. If one needs to format partial, complex or out-of-bounds data, the format function allows building DateTimeComponents specifically for formatting it:

DateTimeComponents.Formats.RFC_1123.format {
    // the receiver of this lambda is DateTimeComponents
    setDate(LocalDate(2023, 1, 7))
    hour = 23
    minute = 59
    second = 60
    setOffset(UtcOffset(hours = 2))
} // Sat, 7 Jan 2023 23:59:60 +0200

Instant arithmetic

val now = Clock.System.now()
val instantInThePast: Instant = Instant.parse("2020-01-01T00:00:00Z")
val durationSinceThen: Duration = now - instantInThePast
val equidistantInstantInTheFuture: Instant = now + durationSinceThen

Duration is a type from the experimental kotlin.time package in the Kotlin standard library. This type holds the amount of time that can be represented in different time units: from nanoseconds to 24H days.

To get the calendar difference between two instants you can use the Instant.periodUntil(Instant, TimeZone) function.

val period: DateTimePeriod = instantInThePast.periodUntil(Clock.System.now(), TimeZone.UTC)

A DateTimePeriod represents a difference between two particular moments as a sum of calendar components, like "2 years, 3 months, 10 days, and 22 hours".

The difference can be calculated as an integer amount of specified date or time units:

val diffInMonths = instantInThePast.until(Clock.System.now(), DateTimeUnit.MONTH, TimeZone.UTC)

There are also shortcuts yearsUntil(...), monthsUntil(...), and daysUntil(...).

A particular amount of date/time units or a date/time period can be added to an Instant with the plus function:

val now = Clock.System.now()
val systemTZ = TimeZone.currentSystemDefault()
val tomorrow = now.plus(2, DateTimeUnit.DAY, systemTZ)
val threeYearsAndAMonthLater = now.plus(DateTimePeriod(years = 3, months = 1), systemTZ)

Note that plus and ...until operations require a TimeZone as a parameter because the calendar interval between two particular instants can be different, when calculated in different time zones.

Date arithmetic

Similar operations with date units are provided for LocalDate type:

  • LocalDate.plus(number, DateTimeUnit.DateBased)
  • LocalDate.plus(DatePeriod)
  • LocalDate.until(LocalDate, DateTimeUnit.DateBased) and the shortcuts yearsUntil, monthUntil, daysUntil
  • LocalDate.periodUntil(LocalDate): DatePeriod and LocalDate.minus(LocalDate): DatePeriod

Notice that, instead of the general DateTimeUnit and DateTimePeriod types, we're using their subtypes DateTimeUnit.DateBased and DatePeriod respectively. This allows preventing the situations when time components are being added to a date at compile time.

Date + time arithmetic

Arithmetic on LocalDateTime is intentionally omitted. The reason for this is that the presence of daylight saving time transitions (changing from standard time to daylight saving time and back) causes LocalDateTime arithmetic to be ill-defined. For example, consider time gaps (or, as dst tag wiki on Stack Overflow calls them, "spring forward" transitions), that is, ranges of date + time combinations that never occur in a given time zone due to clocks moving forward. If we allowed LocalDateTime arithmetic that ignored time zones, then it could result in LocalDateTime instances that are inside a time gap and are invalid in the implied time zone.

Therefore, the recommended way to use a LocalDateTime is to treat it as a representation of an Instant, perform all the required arithmetic on Instant values, and only convert to LocalDateTime when a human-readable representation is needed.

val timeZone = TimeZone.of("Europe/Berlin")
val localDateTime = LocalDateTime.parse("2021-03-27T02:16:20")
val instant = localDateTime.toInstant(timeZone)

val instantOneDayLater = instant.plus(1, DateTimeUnit.DAY, timeZone)
val localDateTimeOneDayLater = instantOneDayLater.toLocalDateTime(timeZone)
// 2021-03-28T03:16:20, as 02:16:20 that day is in a time gap

val instantTwoDaysLater = instant.plus(2, DateTimeUnit.DAY, timeZone)
val localDateTimeTwoDaysLater = instantTwoDaysLater.toLocalDateTime(timeZone)
// 2021-03-29T02:16:20

Implementation

The implementation of date/time types, such as Instant, LocalDateTime, TimeZone and so on, relies on:

Known/open issues, work TBD

  • Some kind of Clock interface is needed as a pluggable replacement for Instant.now().
  • Flexible locale-neutral parsing and formatting facilities are needed to support various date/time interchange formats that are used in practice (in particular, various RFCs).

Using in your projects

Note that the library is experimental, and the API is subject to change.

The library is published to Maven Central.

The library is compatible with the Kotlin Standard Library not lower than 1.9.0.

If you target Android devices running below API 26, you need to use Android Gradle plugin 4.0 or newer and enable core library desugaring.

Gradle

  • Add the Maven Central repository if it is not already there:
repositories {
    mavenCentral()
}
  • In multiplatform projects, add a dependency to the commonMain source set dependencies
kotlin {
    sourceSets {
        commonMain {
             dependencies {
                 implementation("org.jetbrains.kotlinx:kotlinx-datetime:0.6.0-RC.2")
             }
        }
    }
}
  • To use the library in a single-platform project, add a dependency to the dependencies block.
dependencies {
    implementation("org.jetbrains.kotlinx:kotlinx-datetime:0.6.0-RC.2")
}

Note about time zones in JS

By default, there's only one time zone available in Kotlin/JS: the SYSTEM time zone with a fixed offset.

If you want to use all time zones in Kotlin/JS platform, you need to add the following npm dependency:

kotlin {
    sourceSets {
        val jsMain by getting {
            dependencies {
                implementation(npm("@js-joda/timezone", "2.3.0"))
            }
        }
    }
}

and after that add the following initialization code in your project:

@JsModule("@js-joda/timezone")
@JsNonModule
external object JsJodaTimeZoneModule

private val jsJodaTz = JsJodaTimeZoneModule

Maven

Add a dependency to the <dependencies> element. Note that you need to use the platform-specific -jvm artifact in Maven.

<dependency>
    <groupId>org.jetbrains.kotlinx</groupId>
    <artifactId>kotlinx-datetime-jvm</artifactId>
    <version>0.6.0-RC.2</version>
</dependency>

Building

The project requires JDK 8 to build classes and to run tests. Gradle will try to find it among the installed JDKs or provision it automatically if it couldn't be found. The path to JDK 8 can be additionally specified with the environment variable JDK_8. For local builds, you can use a later version of JDK if you don't have that version installed. Specify the version of this JDK with the java.mainToolchainVersion Gradle property.

After that, the project can be opened in IDEA and built with Gradle.

For building and running benchmarks, see README.md

kotlinx-datetime's People

Contributors

bishiboosh avatar cmota avatar dkhalanskyjb avatar elizarov avatar etolstoy avatar fenstonsingel avatar hfhbd avatar ignatberesnev avatar igoriakovlev avatar ilya-g avatar joffrey-bion avatar lion7 avatar lukellmann avatar markcmann avatar nikpachoo avatar ninodlc avatar qurbonzoda avatar qwwdfsad avatar serbelga avatar shanshin avatar swankjesse avatar vanniktech avatar whyoleg avatar wkornewald avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

kotlinx-datetime's Issues

Provide time only representation, e.g. LocalTime

Hey,

Currently there is support for LocalDateTime, but I would like to use some time representation without a date. Ideall would be something like LocalTime for my use case.

my use case:
represent daily events

my current workaround:
use DateTimePeriod with a max of 24h in total

Make Clock.System() replaceable / mockable

Instead of injecting a Clock in every single function or class that uses the usual approach of LocalDateTime.now(), consider adding a way to replace the System clock instance if one wants to.

This would make classes that depend on the abstract context of now easily testable, and idiomatic, as we wouldn't need to inject it everywhere just for the sake of testing.

I'm happy to provide a pull request for this possibility

Crash on Android below API 26 for ClassNotFoundException on java.time.Instant (without desugaring)

When using this library on Android, devices running below API 26 will crash with a class not found exception on java.time.Instant.

I was under the impression we'd transitively get the java time dependencies by simply importing this library, but it won't work unless you enable coreLibraryDesugaring. I'd consider this a bug.

Here's a trace, though I'm sure you don't need it:

    Process: com.package.myapp, PID: 17460
    java.lang.NoClassDefFoundError: Failed resolution of: Ljava/time/Instant;
        at kotlinx.datetime.Instant.<clinit>(Instant.kt:75)
     Caused by: java.lang.ClassNotFoundException: Didn't find class "java.time.Instant" on path: DexPathList[[zip file "/data/app/com.package.myapp/base.apk"],nativeLibraryDirectories=[/data/app/com.package.myapp-1/lib/arm, /vendor/lib, /system/lib]]
        at dalvik.system.BaseDexClassLoader.findClass(BaseDexClassLoader.java:56)
        at java.lang.ClassLoader.loadClass(ClassLoader.java:511)
        at java.lang.ClassLoader.loadClass(ClassLoader.java:469)
        at kotlinx.datetime.Instant.<clinit>(Instant.kt:75)ย 
        at androidx.room.CoroutinesRoom$Companion$createFlow$1$1$1.invokeSuspend(CoroutinesRoom.kt:122)ย 
        at kotlin.coroutines.jvm.internal.BaseContinuationImpl.resumeWith(ContinuationImpl.kt:33)ย 
        at kotlinx.coroutines.DispatchedTask.run(DispatchedTask.kt:106)ย 
        at android.os.Handler.handleCallback(Handler.java:739)ย 
        at android.os.Handler.dispatchMessage(Handler.java:95)ย 
        at android.os.Looper.loop(Looper.java:158)ย 
        at android.app.ActivityThread.main(ActivityThread.java:7224)ย 
        at java.lang.reflect.Method.invoke(Native Method)ย 
        at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1230)ย 
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1120)ย 
    	Suppressed: java.lang.ClassNotFoundException: java.time.Instant
        at java.lang.Class.classForName(Native Method)
        at java.lang.BootClassLoader.findClass(ClassLoader.java:781)
        at java.lang.BootClassLoader.loadClass(ClassLoader.java:841)
        at java.lang.ClassLoader.loadClass(ClassLoader.java:504)
        		... 35 more
     Caused by: java.lang.NoClassDefFoundError: Class not found using the boot class loader; no stack trace available```

How to de/serialize types?

I trying to use this library, and I would like to know how to de/serialize types e.g. LocalDate, LocalDateTime.

Normalize components in DateTimePeriod/DatePeriod

Currently we provide DateTimePeriod type as a bag of several independent components: years, months, days, hours, minutes, seconds, and nanosecodns. This approach leads to several problems:

  • when nanoseconds value exceeds the range [0..10^9), the ISO representation is rendered incorrectly (see #79)
  • there can be several non-equal values of DateTimePeriod that produce the same ISO string representation. Since we intend to use that string representation as the default serialized form for textual formats, it could lead to a situation when deserialized value would be not equal to what was serialized before.

To avoid these problems we propose to do DateTimePeriod component normalization at construction time in the following way:

  • all time components, e.g. hours..nanoseconds are normalized to the single long total value of nanoseconds;
  • days component is stored as is;
  • years and months components are stored together as the total number of months.

Note that this normalization only affects DateTimePeriod storage and internal representation. There shall still remain component properties that will derive values from the normalized internal state. For example, hours property will return the normalized number of nanoseconds divided by 3600 * 10^9, and months will return totalMonths % 12.

This change will have the following consequences:

  • seconds and nanoseconds properties change their type from Long to Int. We may leave a secondary constructor with the long nanoseconds parameter for convenience, though.
  • it may be impossible to fit the difference between extreme dates, such as platform specific min and max dates, as an Int total number of months.
  • the time part of DateTimePeriod will be limited to the ยฑ292 year range. This usually isn't a practical concern because the time part doesn't exceed 24H in most cases.

LocalDateTime arithmetic

Currently, the ReadMe does not cover LocalDateTime arithmetic. Either make this arithmetic clear by adding this to the Instant arithmetic, with needs a timeZone.

val localDateTime: LocalDateTime = ...
val timeZone: TimeZone = ...
val futureLocalDateTime = (localDateTime.toInstant(timeZone) + 7.days).toLocalDateTime(timeZone)

Or add LocalDateTime arithmetic without a TimeZone, which can result into an overflow, like the java.time API.

val localDateTime: LocalDateTime = ...
val futureLocalDateTime = localDateTime + 7.days
// java.time overflow arithmetic
public LocalDateTime plusHours(long hours) {
    return plusWithOverflow(date, hours, 0, 0, 0, 1);
}

I can submit a PR with LocalDateTime arithmetic, if wanted.

Export types to JavaScript

Hello,

Is there any reason, why library classes are not exported to JS using @JsExport?
I would love to use kotlinx-datetime in multiplatform library module compiled to JS using recently introduced IR backend.
Library is used by Typescript-based project, so without JS exports my compiled classes and corresponding d.ts file are only partially usable.

From Kotlin documentation:

If you are targeting the IR compiler backend, you must use the @JsExport annotation to make your functions visible from Kotlin in the first place.

Is that lack of export a design decision, or a missing feature?

[JS] DateTimeException: unsupported ZoneId: Europe/Berlin

From the README:

val tzBerlin = TimeZone.of("Europe/Berlin")

Result in Kotlin/JS:

IllegalTimeZoneExceptionย {message: "DateTimeException: unsupported ZoneId:Europe/Berlin", cause: JsJodaException, name: "IllegalTimeZoneException", stack: "DateTimeException: unsupported ZoneId:Europe/Berlin โ€ฆ"}

Either there's a bug or the documentation lacks some info about how to use time zones. I guess js-joda-timezone is needed.

Alternative JVM implementation for Android

From plans (in readme.md):

An alternative JVM implementation for Android might be needed.

Current JVM implementation (based on JodaTime) have some cons, that can be avoided by using, for example, ThreeTenABP.

  1. Why not use ThreeTenBP?
    Similar to the problems with using Joda-Time on Android, the threetenbp uses a JAR resource for loading timezone information. This is an extremely inefficient mechanism on Android.
    This library places the timezone information as a standard Android asset and provides a custom loader for parsing it efficiently.
  2. Why not use Joda-Time?
    Joda-Time has a very large API which brings with it a very large binary size and large method count. The creator of both JSR-310 and Joda-Time has also said that while Joda-Time isn't broken, it does have design flaws.
    If you are using Joda-Time already, there's little reason to switch unless its size or method count is relevant to you. For new projects, however, this library offers the standard APIs in Java 8 as a much smaller package in not only binary size and method count, but also in API size.

Instant lacking truncatedTo() functionality

Migration from the java.time library was smooth-ish except I noticed it's missing truncation operations on Instant.

Clock.System.now().truncatedTo(ChronoUnit.MINUTES)

I'd like to request porting of this functionality in this library.

KampKit dependency error on iOS - 'Can't find kotlinx-datetime-iosarm64'

@asarazan and I were not able to build on iOS for a kampkit project. Any idea how to resolve it? Much appreciated!

Here are some of the error logs:

REPO_ROOT="$PODS_TARGET_SRCROOT"
"$REPO_ROOT/../gradlew" -p "$REPO_ROOT" :shared:syncFramework                     -Pkotlin.native.cocoapods.target=$KOTLIN_TARGET                     -Pkotlin.native.cocoapods.configuration=$CONFIGURATION                     -Pkotlin.native.cocoapods.cflags="$OTHER_CFLAGS"                     -Pkotlin.native.cocoapods.paths.headers="$HEADER_SEARCH_PATHS"                     -Pkotlin.native.cocoapods.paths.frameworks="$FRAMEWORK_SEARCH_PATHS"
Starting a Gradle Daemon, 2 incompatible Daemons could not be reused, use --status for details
> Task :buildSrc:compileKotlin UP-TO-DATE
> Task :buildSrc:compileJava NO-SOURCE
> Task :buildSrc:compileGroovy NO-SOURCE
> Task :buildSrc:pluginDescriptors UP-TO-DATE
> Task :buildSrc:processResources NO-SOURCE
> Task :buildSrc:classes UP-TO-DATE
> Task :buildSrc:inspectClassesForKotlinIC UP-TO-DATE
> Task :buildSrc:jar UP-TO-DATE
> Task :buildSrc:assemble UP-TO-DATE
> Task :buildSrc:compileTestKotlin NO-SOURCE
> Task :buildSrc:pluginUnderTestMetadata UP-TO-DATE
> Task :buildSrc:compileTestJava NO-SOURCE
> Task :buildSrc:compileTestGroovy NO-SOURCE
> Task :buildSrc:processTestResources NO-SOURCE
> Task :buildSrc:testClasses UP-TO-DATE
> Task :buildSrc:test NO-SOURCE
> Task :buildSrc:validateTaskProperties UP-TO-DATE
> Task :buildSrc:check UP-TO-DATE
> Task :buildSrc:build UP-TO-DATE

> Configure project :shared
Kotlin Multiplatform Projects are an experimental feature.

> Task :shared:generateIosMainKaMPKitDbInterface UP-TO-DATE
The message received from the daemon indicates that the daemon has disappeared.
Build request sent: Build{id=269dc66a-5a83-490e-9fcb-d54ce0e56755, currentDir=/Users/benjaminlim/Desktop/gameface-kampkit/ios/Pods}
Attempting to read last messages from the daemon log...
Daemon pid: 21010
  log file: /Users/benjaminlim/.gradle/daemon/5.6.4/daemon-21010.out.log
----- Last  20 lines from daemon log file - daemon-21010.out.log -----
10:15:17.009 [DEBUG] [org.gradle.cache.internal.DefaultFileLockManager] Waiting to acquire exclusive lock on daemon addresses registry.
10:15:17.009 [DEBUG] [org.gradle.cache.internal.DefaultFileLockManager] Lock acquired on daemon addresses registry.
10:15:17.011 [DEBUG] [org.gradle.cache.internal.DefaultFileLockManager] Releasing lock on daemon addresses registry.
10:15:17.013 [DEBUG] [org.gradle.launcher.daemon.server.DaemonStateCoordinator] resetting idle timer
10:15:17.014 [DEBUG] [org.gradle.launcher.daemon.server.DaemonStateCoordinator] daemon is running. Sleeping until state changes.
10:15:17.014 [INFO] [org.gradle.launcher.daemon.server.exec.StartBuildOrRespondWithBusy] Daemon is about to start building Build{id=269dc66a-5a83-490e-9fcb-d54ce0e56755, currentDir=/Users/benjaminlim/Desktop/gameface-kampkit/ios/Pods}. Dispatching build started information...
10:15:17.014 [DEBUG] [org.gradle.launcher.daemon.server.SynchronizedDispatchConnection] thread 19: dispatching class org.gradle.launcher.daemon.protocol.BuildStarted
10:15:17.017 [DEBUG] [org.gradle.launcher.daemon.server.exec.EstablishBuildEnvironment] Configuring env variables: {PATH=/Applications/Xcode-beta.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin:/Applications/Xcode-beta.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/local/bin:/Applications/Xcode-beta.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/libexec:/Applications/Xcode-beta.app/Contents/Developer/Platforms/iPhoneOS.platform/usr/bin:/Applications/Xcode-beta.app/Contents/Developer/Platforms/iPhoneOS.platform/usr/local/bin:/Applications/Xcode-beta.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/usr/bin:/Applications/Xcode-beta.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/usr/local/bin:/Applications/Xcode-beta.app/Contents/Developer/usr/bin:/Applications/Xcode-beta.app/Contents/Developer/usr/local/bin:/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin, LLBUILD_TASK_ID=512000a0002, LLBUILD_BUILD_ID=1851983122, DEBUGGING_SYMBOLS=YES, EXCLUDED_INSTALLSRC_SUBDIRECTORY_PATTERNS=.DS_Store .svn .git .hg CVS, DEVELOPMENT_LANGUAGE=en, BUNDLE_FORMAT=shallow, SYSTEM_DEVELOPER_USR_DIR=/Applications/Xcode-beta.app/Contents/Developer/usr, BUILD_VARIANTS=normal, LIBRARY_FLAG_NOSPACE=YES, CODESIGNING_FOLDER_PATH=/Users/benjaminlim/Library/Developer/Xcode/DerivedData/KaMPKitiOS-czccbxoiggfeplculcfguxucvfdv/Build/Products/Debug-iphoneos/shared/, INSTALL_ROOT=/tmp/Pods.dst, DWARF_DSYM_FILE_NAME=.dSYM, ARCHS_UNIVERSAL_IPHONE_OS=armv7 arm64, TARGET_DEVICE_MODEL=iPhone12,1, JAVA_SOURCE_SUBDIR=., CLANG_WARN_CONSTANT_CONVERSION=YES, CURRENT_ARCH=undefined_arch, VALIDATE_WORKSPACE=YES_ERROR, LINKER_DISPLAYS_MANGLED_NAMES=NO, PASCAL_STRINGS=YES, CONFIGURATION=Debug, TARGET_DEVICE_OS_VERSION=13.5.1, DEFAULT_KEXT_INSTALL_PATH=/System/Library/Extensions, SCRIPT_INPUT_FILE_COUNT=0, SUPPORTS_MAC_DESIGNED_FOR_IPHONE_IPAD=YES, INSTALLHDRS_COPY_PHASE=NO, UID=501, SDK_DIR=/Applications/Xcode-beta.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS14.0.sdk, SED=/usr/bin/sed, PODS_BUILD_DIR=/Users/benjaminlim/Library/Developer/Xcode/DerivedData/KaMPKitiOS-czccbxoiggfeplculcfguxucvfdv/Build/Products, DERIVED_SOURCES_DIR=/Users/benjaminlim/Library/Developer/Xcode/DerivedData/KaMPKitiOS-czccbxoiggfeplculcfguxucvfdv/Build/Intermediates.noindex/Pods.build/Debug-iphoneos/shared.build/DerivedSources, LOCAL_ADMIN_APPS_DIR=/Applications/Utilities, PODS_TARGET_SRCROOT=/Users/benjaminlim/Desktop/gameface-kampkit/ios/Pods/../../shared, DEPLOYMENT_TARGET_SUGGESTED_VALUES=9.0 9.1 9.2 9.3 10.0 10.1 10.2 10.3 11.0 11.1 11.2 11.3 11.4 12.0 12.1 12.2 12.3 12.4 13.0 13.1 13.2 13.3 13.4 13.5 14.0, USE_LLVM_TARGET_TRIPLES_FOR_CLANG=YES, PROFILING_CODE=NO, SYSTEM_KEXT_INSTALL_PATH=/System/Library/Extensions, BUILD_LIBRARY_FOR_DISTRIBUTION=NO, BUNDLE_FRAMEWORKS_FOLDER_PATH=Frameworks, APPLE_INTERNAL_DEVELOPER_DIR=/AppleInternal/Developer, COMPRESS_PNG_FILES=YES, LLVM_TARGET_TRIPLE_VENDOR=apple, BUILD_DIR=/Users/benjaminlim/Library/Developer/Xcode/DerivedData/KaMPKitiOS-czccbxoiggfeplculcfguxucvfdv/Build/Products, REMOVE_SVN_FROM_RESOURCES=YES, CONFIGURATION_BUILD_DIR=/Users/benjaminlim/Library/Developer/Xcode/DerivedData/KaMPKitiOS-czccbxoiggfeplculcfguxucvfdv/Build/Products/Debug-iphoneos/shared, PRECOMP_DESTINATION_DIR=/Users/benjaminlim/Library/Developer/Xcode/DerivedData/KaMPKitiOS-czccbxoiggfeplculcfguxucvfdv/Build/Intermediates.noindex/Pods.build/Debug-iphoneos/shared.build/PrefixHeaders, PROJECT_FILE_PATH=/Users/benjaminlim/Desktop/gameface-kampkit/ios/Pods/Pods.xcodeproj, LOCAL_DEVELOPER_DIR=/Library/Developer, APP_NAME_20985=Gradle, DEPLOYMENT_TARGET_CLANG_FLAG_NAME=miphoneos-version-min, SYSTEM_DEVELOPER_BIN_DIR=/Applications/Xcode-beta.app/Contents/Developer/usr/bin, OBJECT_FILE_DIR_normal=/Users/benjaminlim/Library/Developer/Xcode/DerivedData/KaMPKitiOS-czccbxoiggfeplculcfguxucvfdv/Build/Intermediates.noindex/Pods.build/Debug-iphoneos/shared.build/Objects-normal, CP=/bin/cp, STRIP_SWIFT_SYMBOLS=YES, ENABLE_PREVIEWS=NO, SYSTEM_DEVELOPER_PERFORMANCE_TOOLS_DIR=/Applications/Xcode-beta.app/Contents/Developer/Applications/Performance Tools, CONFIGURATION_TEMP_DIR=/Users/benjaminlim/Library/Developer/Xcode/DerivedData/KaMPKitiOS-czccbxoiggfeplculcfguxucvfdv/Build/Intermediates.noindex/Pods.build/Debug-iphoneos, CLASS_FILE_DIR=/Users/benjaminlim/Library/Developer/Xcode/DerivedData/KaMPKitiOS-czccbxoiggfeplculcfguxucvfdv/Build/Intermediates.noindex/Pods.build/Debug-iphoneos/shared.build/JavaClasses, com.apple.java.jvmTask=CommandLine, arch=undefined_arch, JAVA_ZIP_FLAGS=-urg, CODE_SIGN_IDENTITY=iPhone Developer, LOCALIZED_STRING_SWIFTUI_SUPPORT=YES, CLANG_WARN_STRICT_PROTOTYPES=YES, BUNDLE_PLUGINS_FOLDER_PATH=PlugIns, SYSTEM_DEVELOPER_DIR=/Applications/Xcode-beta.app/Contents/Developer, VERBOSE_PBXCP=NO, GCC_VERSION_IDENTIFIER=com_apple_compilers_llvm_clang_1_0, CLANG_WARN_OBJC_ROOT_CLASS=YES_ERROR, ENABLE_TESTABILITY=YES, LOGNAME=benjaminlim, CURRENT_VARIANT=normal, SDK_DIR_iphoneos14_0=/Applications/Xcode-beta.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS14.0.sdk, ENABLE_BITCODE=YES, APP_ICON_20985=/Users/benjaminlim/Desktop/gameface-kampkit/media/gradle.icns, TREAT_MISSING_BASELINES_AS_TEST_FAILURES=NO, HEADERMAP_INCLUDES_NONPUBLIC_NONPRIVATE_HEADERS=YES, APPLE_INTERNAL_TOOLS=/AppleInternal/Developer/Tools, OLDPWD=/Users/benjaminlim/Desktop/gameface-kampkit, USE_LLVM_TARGET_TRIPLES_FOR_LD=YES, DERIVE_MACCATALYST_PRODUCT_BUNDLE_IDENTIFIER=NO, ARCHS_STANDARD_32_64_BIT=armv7 arm64, COLOR_DIAGNOSTICS=NO, DEAD_CODE_STRIPPING=YES, CODE_SIGN_INJECT_BASE_ENTITLEMENTS=YES, KEEP_PRIVATE_EXTERNS=NO, SYSTEM_APPS_DIR=/Applications, SYSTEM_ADMIN_APPS_DIR=/Applications/Utilities, HEADERMAP_USES_FRAMEWORK_PREFIX_ENTRIES=YES, __CF_USER_TEXT_ENCODING=0x1F5:0:15, BITCODE_GENERATION_MODE=marker, SHARED_DERIVED_FILE_DIR=/Users/benjaminlim/Library/Developer/Xcode/DerivedData/KaMPKitiOS-czccbxoiggfeplculcfguxucvfdv/Build/Products/Debug-iphoneos/shared/DerivedSources, METAL_LIBRARY_OUTPUT_DIR=/Users/benjaminlim/Library/Developer/Xcode/DerivedData/KaMPKitiOS-czccbxoiggfeplculcfguxucvfdv/Build/Products/Debug-iphoneos/shared/, GENERATE_TEXT_BASED_STUBS=NO, APPLY_RULES_IN_COPY_HEADERS=NO, JAVA_FRAMEWORK_RESOURCES_DIRS=Resources, SEPARATE_SYMBOL_EDIT=NO, ARCHS_STANDARD=armv7 arm64, CODE_SIGNING_ALLOWED=NO, GENERATE_MASTER_OBJECT_FILE=NO, USE_HEADERMAP=YES, TOOLCHAIN_DIR=/Applications/Xcode-beta.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain, ENABLE_ON_DEMAND_RESOURCES=NO, DEVELOPER_TOOLS_DIR=/Applications/Xcode-beta.app/Contents/Developer/Tools, UNSTRIPPED_PRODUCT=NO, FILE_LIST=/Users/benjaminlim/Library/Developer/Xcode/DerivedData/KaMPKitiOS-czccbxoiggfeplculcfguxucvfdv/Build/Intermediates.noindex/Pods.build/Debug-iphoneos/shared.build/Objects/LinkFileList, TARGET_TEMP_DIR=/Users/benjaminlim/Library/Developer/Xcode/DerivedData/KaMPKitiOS-czccbxoiggfeplculcfguxucvfdv/Build/Intermediates.noindex/Pods.build/Debug-iphoneos/shared.build, SDK_VERSION_MINOR=000, GCC_OPTIMIZATION_LEVEL=0, PROJECT_DERIVED_FILE_DIR=/Users/benjaminlim/Library/Developer/Xcode/DerivedData/KaMPKitiOS-czccbxoiggfeplculcfguxucvfdv/Build/Intermediates.noindex/Pods.build/DerivedSources, INLINE_PRIVATE_FRAMEWORKS=NO, ACTION=build, DEVELOPER_FRAMEWORKS_DIR_QUOTED=/Applications/Xcode-beta.app/Contents/Developer/Library/Frameworks, GCC_NO_COMMON_BLOCKS=YES, CODE_SIGNING_REQUIRED=YES, NATIVE_ARCH_64_BIT=x86_64, ARCHS_STANDARD_INCLUDING_64_BIT=armv7 arm64, CLANG_WARN_INT_CONVERSION=YES, HOME=/Users/benjaminlim, HEADERMAP_USES_VFS=NO, WRAP_ASSET_PACKS_IN_SEPARATE_DIRECTORIES=NO, PRODUCT_SETTINGS_PATH=, PLATFORM_DEVELOPER_BIN_DIR=/Applications/Xcode-beta.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/usr/bin, ARCHS=arm64, PLATFORM_DEVELOPER_APPLICATIONS_DIR=/Applications/Xcode-beta.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/Applications, SDKROOT=/Applications/Xcode-beta.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS14.0.sdk, STRIP_BITCODE_FROM_COPIED_FILES=YES, NATIVE_ARCH=armv7, HEADERMAP_INCLUDES_FLAT_ENTRIES_FOR_TARGET_BEING_BUILT=YES, DEVELOPER_APPLICATIONS_DIR=/Applications/Xcode-beta.app/Contents/Developer/Applications, USER_LIBRARY_DIR=/Users/benjaminlim/Library, ARCHS_STANDARD_32_BIT=armv7, GCC_TREAT_WARNINGS_AS_ERRORS=NO, KOTLIN_TARGET=ios_arm, CLANG_WARN_OBJC_LITERAL_CONVERSION=YES, OSAC=/usr/bin/osacompile, DEVELOPER_DIR=/Applications/Xcode-beta.app/Contents/Developer, XCODE_VERSION_MAJOR=1200, LOCSYMROOT=/Users/benjaminlim/Desktop/gameface-kampkit/ios/Pods, ALTERNATE_MODE=u+w,go-w,a+rX, XPCSERVICES_FOLDER_PATH=/XPCServices, XPC_FLAGS=0x0, MODULE_CACHE_DIR=/Users/benjaminlim/Library/Developer/Xcode/DerivedData/ModuleCache.noindex, GCC_WARN_UNINITIALIZED_AUTOS=YES_AGGRESSIVE, SDK_NAMES=iphoneos14.0, BUNDLE_EXECUTABLE_FOLDER_NAME_deep=MacOS, CA_ASSERT_MAIN_THREAD_TRANSACTIONS=1, SHLVL=2, YACC=yacc, PLATFORM_NAME=iphoneos, DERIVED_FILE_DIR=/Users/benjaminlim/Library/Developer/Xcode/DerivedData/KaMPKitiOS-czccbxoiggfeplculcfguxucvfdv/Build/Intermediates.noindex/Pods.build/Debug-iphoneos/shared.build/DerivedSources, CLONE_HEADERS=NO, REMOVE_HG_FROM_RESOURCES=YES, GCC_WARN_64_TO_32_BIT_CONVERSION=YES, SKIP_INSTALL=YES, ONLY_ACTIVE_ARCH=YES, CORRESPONDING_SIMULATOR_SDK_DIR=/Applications/Xcode-beta.app/Contents/Developer/Platforms/iPhoneSimulator.platform/Developer/SDKs/iPhoneSimulator14.0.sdk, VERSION_INFO_BUILDER=benjaminlim, INFOPLIST_OUTPUT_FORMAT=binary, SCRIPT_INPUT_FILE_LIST_COUNT=0, COPY_PHASE_STRIP=NO, METAL_LIBRARY_FILE_BASE=default, SYSTEM_DEVELOPER_RELEASENOTES_DIR=/Applications/Xcode-beta.app/Contents/Developer/ADC Reference Library/releasenotes, LIBRARY_DEXT_INSTALL_PATH=/Library/DriverExtensions, CLANG_CXX_LIBRARY=libc++, VALID_ARCHS=arm64 arm64e armv7 armv7s, PLATFORM_DISPLAY_NAME=iOS, SYSTEM_LIBRARY_DIR=/System/Library, JAVA_JAR_FLAGS=cv, EMBED_ASSET_PACKS_IN_PRODUCT_BUNDLE=NO, MAC_OS_X_VERSION_MINOR=1505, GENERATE_PROFILING_CODE=NO, CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS=YES, ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES=NO, DEPLOYMENT_TARGET_CLANG_ENV_NAME=IPHONEOS_DEPLOYMENT_TARGET, JAVA_APP_STUB=/System/Library/Frameworks/JavaVM.framework/Resources/MacOS/JavaApplicationStub, APPLE_INTERNAL_DIR=/AppleInternal, COMBINE_HIDPI_IMAGES=NO, XCODE_APP_SUPPORT_DIR=/Applications/Xcode-beta.app/Contents/Developer/Library/Xcode, INFOPLIST_EXPAND_BUILD_SETTINGS=YES, REZ_COLLECTOR_DIR=/Users/benjaminlim/Library/Developer/Xcode/DerivedData/KaMPKitiOS-czccbxoiggfeplculcfguxucvfdv/Build/Intermediates.noindex/Pods.build/Debug-iphoneos/shared.build/ResourceManagerResources, CLANG_WARN_DIRECT_OBJC_ISA_USAGE=YES_ERROR, MAC_OS_X_VERSION_ACTUAL=101505, SYSTEM_DEVELOPER_TOOLS_RELEASENOTES_DIR=/Applications/Xcode-beta.app/Contents/Developer/ADC Reference Library/releasenotes/DeveloperTools, CLEAN_PRECOMPS=YES, REMOVE_CVS_FROM_RESOURCES=YES, ALTERNATE_OWNER=benjaminlim, DWARF_DSYM_FILE_SHOULD_ACCOMPANY_PRODUCT=NO, DEPLOYMENT_POSTPROCESSING=NO, GCC_WARN_ABOUT_RETURN_TYPE=YES_ERROR, COPY_HEADERS_RUN_UNIFDEF=NO, SWIFT_PLATFORM_TARGET_PREFIX=ios, PLATFORM_DEVELOPER_TOOLS_DIR=/Applications/Xcode-beta.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/Tools, GCC_DYNAMIC_NO_PIC=NO, SYSTEM_DEVELOPER_DOC_DIR=/Applications/Xcode-beta.app/Contents/Developer/ADC Reference Library, ENABLE_STRICT_OBJC_MSGSEND=YES, SYSTEM_DEXT_INSTALL_PATH=/System/Library/DriverExtensions, LD_NO_PIE=NO, ENABLE_TESTING_SEARCH_PATHS=NO, PRODUCT_BUNDLE_IDENTIFIER=org.cocoapods.shared, TARGET_NAME=shared, SDK_PRODUCT_BUILD_VERSION=18A5332e, SWIFT_OPTIMIZATION_LEVEL=-Onone, LEGACY_DEVELOPER_DIR=/Applications/Xcode-beta.app/Contents/PlugIns/Xcode3Core.ideplugin/Contents/SharedSupport/Developer, JAVA_ARCHIVE_CLASSES=YES, CREATE_INFOPLIST_SECTION_IN_BINARY=NO, FIXED_FILES_DIR=/Users/benjaminlim/Library/Developer/Xcode/DerivedData/KaMPKitiOS-czccbxoiggfeplculcfguxucvfdv/Build/Intermediates.noindex/Pods.build/Debug-iphoneos/shared.build/FixedFiles, ALTERNATE_GROUP=staff, CLANG_WARN__DUPLICATE_METHOD_MATCH=YES, NO_COMMON=YES, GCC_PFE_FILE_C_DIALECTS=c objective-c c++ objective-c++, LD_RUNPATH_SEARCH_PATHS= @executable_path/Frameworks, REZ_OBJECTS_DIR=/Users/benjaminlim/Library/Developer/Xcode/DerivedData/KaMPKitiOS-czccbxoiggfeplculcfguxucvfdv/Build/Intermediates.noindex/Pods.build/Debug-iphoneos/shared.build/ResourceManagerResources/Objects, USE_LLVM_TARGET_TRIPLES_FOR_TAPI=YES, PODS_CONFIGURATION_BUILD_DIR=/Users/benjaminlim/Library/Developer/Xcode/DerivedData/KaMPKitiOS-czccbxoiggfeplculcfguxucvfdv/Build/Products/Debug-iphoneos, GCC_THUMB_SUPPORT=YES, COPYING_PRESERVES_HFS_DATA=NO, JAVA_ARCH=x86_64, LOCAL_LIBRARY_DIR=/Library, MTL_FAST_MATH=YES, FRAMEWORK_SEARCH_PATHS= "/Users/benjaminlim/Desktop/gameface-kampkit/ios/Pods/../../shared/build/cocoapods/framework", CLANG_CXX_LANGUAGE_STANDARD=gnu++14, BUILD_STYLE=, STRINGS_FILE_OUTPUT_ENCODING=binary, PLATFORM_DIR=/Applications/Xcode-beta.app/Contents/Developer/Platforms/iPhoneOS.platform, TEMP_FILES_DIR=/Users/benjaminlim/Library/Developer/Xcode/DerivedData/KaMPKitiOS-czccbxoiggfeplculcfguxucvfdv/Build/Intermediates.noindex/Pods.build/Debug-iphoneos/shared.build, OBJROOT=/Users/benjaminlim/Library/Developer/Xcode/DerivedData/KaMPKitiOS-czccbxoiggfeplculcfguxucvfdv/Build/Intermediates.noindex, LINK_WITH_STANDARD_LIBRARIES=YES, CLANG_MODULES_BUILD_SESSION_FILE=/Users/benjaminlim/Library/Developer/Xcode/DerivedData/ModuleCache.noindex/Session.modulevalidation, TARGET_DEVICE_IDENTIFIER=00008030-000958140E43802E, OS=MACOS, INFOPLIST_PREPROCESS=NO, VALIDATE_DEVELOPMENT_ASSET_PATHS=YES_ERROR, LLBUILD_LANE_ID=10, ASSETCATALOG_FILTER_FOR_DEVICE_MODEL=iPhone12,1, GCC_C_LANGUAGE_STANDARD=gnu11, HEADERMAP_INCLUDES_FRAMEWORK_ENTRIES_FOR_ALL_PRODUCT_TYPES=YES, XCODE_VERSION_ACTUAL=1200, TEST_LIBRARY_SEARCH_PATHS= /Applications/Xcode-beta.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/usr/lib, SYSTEM_DOCUMENTATION_DIR=/Library/Documentation, LOCAL_APPS_DIR=/Applications, LEX=lex, JAVA_ARCHIVE_TYPE=JAR, LIBRARY_KEXT_INSTALL_PATH=/Library/Extensions, TARGET_BUILD_DIR=/Users/benjaminlim/Library/Developer/Xcode/DerivedData/KaMPKitiOS-czccbxoiggfeplculcfguxucvfdv/Build/Products/Debug-iphoneos/shared, TAPI_VERIFY_MODE=ErrorsOnly, CORRESPONDING_SIMULATOR_PLATFORM_NAME=iphonesimulator, PRESERVE_DEAD_CODE_INITS_AND_TERMS=NO, OTHER_LDFLAGS= -l"c++", ENABLE_DEFAULT_HEADER_SEARCH_PATHS=YES, APPLY_RULES_IN_COPY_FILES=NO, USE_LLVM_TARGET_TRIPLES=YES, CORRESPONDING_SIMULATOR_SDK_NAME=iphonesimulator14.0, INSTALL_OWNER=benjaminlim, PLATFORM_DEVELOPER_SDK_DIR=/Applications/Xcode-beta.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/SDKs, GCC_WARN_UNUSED_VARIABLE=YES, DT_TOOLCHAIN_DIR=/Applications/Xcode-beta.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain, TARGETED_DEVICE_FAMILY=1,2, APPLE_INTERNAL_DOCUMENTATION_DIR=/AppleInternal/Documentation, CLANG_WARN_INFINITE_RECURSION=YES, BUNDLE_CONTENTS_FOLDER_PATH_deep=Contents/, USE_RECURSIVE_SCRIPT_INPUTS_IN_SCRIPT_PHASES=YES, SHALLOW_BUNDLE=NO, PRECOMPS_INCLUDE_HEADERS_FROM_BUILT_PRODUCTS_DIR=YES, TEST_FRAMEWORK_SEARCH_PATHS= /Applications/Xcode-beta.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/Library/Frameworks /Applications/Xcode-beta.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS14.0.sdk/Developer/Library/Frameworks, SUPPORTED_DEVICE_FAMILIES=1,2, PROJECT_DIR=/Users/benjaminlim/Desktop/gameface-kampkit/ios/Pods, VERSION_INFO_FILE=shared_vers.c, SYSTEM_DEVELOPER_UTILITIES_DIR=/Applications/Xcode-beta.app/Contents/Developer/Applications/Utilities, LINK_FILE_LIST_normal_arm64=/Users/benjaminlim/Library/Developer/Xcode/DerivedData/KaMPKitiOS-czccbxoiggfeplculcfguxucvfdv/Build/Intermediates.noindex/Pods.build/Debug-iphoneos/shared.build/Objects-normal/arm64/shared.LinkFileList, GROUP=staff, SYSTEM_DEVELOPER_JAVA_TOOLS_DIR=/Applications/Xcode-beta.app/Contents/Developer/Applications/Java Tools, GCC_WARN_UNDECLARED_SELECTOR=YES, EFFECTIVE_PLATFORM_NAME=-iphoneos, PER_ARCH_OBJECT_FILE_DIR=/Users/benjaminlim/Library/Developer/Xcode/DerivedData/KaMPKitiOS-czccbxoiggfeplculcfguxucvfdv/Build/Intermediates.noindex/Pods.build/Debug-iphoneos/shared.build/Objects-normal/undefined_arch, ENABLE_HEADER_DEPENDENCIES=YES, JAVAC_DEFAULT_FLAGS=-J-Xms64m -J-XX:NewSize=4M -J-Dfile.encoding=UTF8, ASSETCATALOG_COMPILER_APPICON_NAME=AppIcon, USE_DYNAMIC_NO_PIC=YES, TARGETNAME=shared, TEMP_DIR=/Users/benjaminlim/Library/Developer/Xcode/DerivedData/KaMPKitiOS-czccbxoiggfeplculcfguxucvfdv/Build/Intermediates.noindex/Pods.build/Debug-iphoneos/shared.build, DEVELOPER_SDK_DIR=/Applications/Xcode-beta.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs, LOCALIZED_STRING_MACRO_NAMES=NSLocalizedString CFCopyLocalizedString, CCHROOT=/var/folders/8q/7x399f1924g4hq82xs2kzb1r0000gn/C/com.apple.DeveloperTools/12.0-12A8169g/Xcode, VERSION_INFO_STRING="@(#)PROGRAM:shared  PROJECT:Pods-", INSTALL_MODE_FLAG=u+w,go-w,a+rX, GCC_PREPROCESSOR_DEFINITIONS=POD_CONFIGURATION_DEBUG=1 DEBUG=1  COCOAPODS=1, CLANG_WARN_ENUM_CONVERSION=YES, SCRIPT_OUTPUT_FILE_LIST_COUNT=0, BUILD_ROOT=/Users/benjaminlim/Library/Developer/Xcode/DerivedData/KaMPKitiOS-czccbxoiggfeplculcfguxucvfdv/Build/Products, CLANG_WARN_BOOL_CONVERSION=YES, CLANG_WARN_SUSPICIOUS_MOVE=YES, SYSTEM_DEVELOPER_APPS_DIR=/Applications/Xcode-beta.app/Contents/Developer/Applications, variant=normal, DEFAULT_DEXT_INSTALL_PATH=/System/Library/DriverExtensions, CLANG_WARN_NON_LITERAL_NULL_CONVERSION=YES, CLANG_ENABLE_OBJC_WEAK=YES, PROJECT=Pods, SHELL=/bin/zsh, REMOVE_GIT_FROM_RESOURCES=YES, DEVELOPER_USR_DIR=/Applications/Xcode-beta.app/Contents/Developer/usr, MTL_ENABLE_DEBUG_INFO=INCLUDE_SOURCE, PLATFORM_PREFERRED_ARCH=arm64, ENABLE_HARDENED_RUNTIME=NO, DEFINES_MODULE=NO, SYSTEM_CORE_SERVICES_DIR=/System/Library/CoreServices, LLVM_TARGET_TRIPLE_OS_VERSION=ios8.0, PLATFORM_FAMILY_NAME=iOS, CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING=YES, AVAILABLE_PLATFORMS=appletvos appletvsimulator iphoneos iphonesimulator macosx watchos watchsimulator, OBJECT_FILE_DIR=/Users/benjaminlim/Library/Developer/Xcode/DerivedData/KaMPKitiOS-czccbxoiggfeplculcfguxucvfdv/Build/Intermediates.noindex/Pods.build/Debug-iphoneos/shared.build/Objects, SUPPORTED_PLATFORMS=iphoneos iphonesimulator, SRCROOT=/Users/benjaminlim/Desktop/gameface-kampkit/ios/Pods, REMOVE_HEADERS_FROM_EMBEDDED_BUNDLES=YES, PLATFORM_DEVELOPER_USR_DIR=/Applications/Xcode-beta.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/usr, TEMP_FILE_DIR=/Users/benjaminlim/Library/Developer/Xcode/DerivedData/KaMPKitiOS-czccbxoiggfeplculcfguxucvfdv/Build/Intermediates.noindex/Pods.build/Debug-iphoneos/shared.build, DEBUG_INFORMATION_FORMAT=dwarf, ALWAYS_USE_SEPARATE_HEADERMAPS=NO, GCC_WARN_UNUSED_FUNCTION=YES, HEADERMAP_INCLUDES_PROJECT_HEADERS=YES, DONT_GENERATE_INFOPLIST_FILE=NO, ICONV=/usr/bin/iconv, DEPLOYMENT_LOCATION=NO, XPC_SERVICE_NAME=0, CLANG_ENABLE_MODULES=YES, USE_HEADER_SYMLINKS=NO, SYMROOT=/Users/benjaminlim/Library/Developer/Xcode/DerivedData/KaMPKitiOS-czccbxoiggfeplculcfguxucvfdv/Build/Products, INSTALL_GROUP=staff, RECURSIVE_SEARCH_PATHS_FOLLOW_SYMLINKS=YES, SUPPORTS_TEXT_BASED_API=NO, APPLE_INTERNAL_LIBRARY_DIR=/AppleInternal/Library, LD_QUOTE_LINKER_ARGUMENTS_FOR_COMPILER_DRIVER=YES, GCC3_VERSION=3.3, DEPLOYMENT_TARGET_LD_FLAG_NAME=ios_version_min, GENERATE_PKGINFO_FILE=NO, INSTALLHDRS_SCRIPT_PHASE=NO, LOCROOT=/Users/benjaminlim/Desktop/gameface-kampkit/ios/Pods, LD_GENERATE_MAP_FILE=NO, DEVELOPER_FRAMEWORKS_DIR=/Applications/Xcode-beta.app/Contents/Developer/Library/Frameworks, VALIDATE_PRODUCT=NO, SHARED_PRECOMPS_DIR=/Users/benjaminlim/Library/Developer/Xcode/DerivedData/KaMPKitiOS-czccbxoiggfeplculcfguxucvfdv/Build/Intermediates.noindex/PrecompiledHeaders, ENTITLEMENTS_REQUIRED=YES, SDK_VERSION_MAJOR=140000, SET_DIR_MODE_OWNER_GROUP=YES, DO_HEADER_SCANNING_IN_JAM=NO, SDK_NAME=iphoneos14.0, NATIVE_ARCH_32_BIT=i386, PWD=/Users/benjaminlim/Desktop/gameface-kampkit/ios/Pods, USER_APPS_DIR=/Users/benjaminlim/Applications, TOOLCHAINS=com.apple.dt.toolchain.XcodeDefault, XCODE_VERSION_MINOR=1200, IPHONEOS_DEPLOYMENT_TARGET=8.0, PER_VARIANT_OBJECT_FILE_DIR=/Users/benjaminlim/Library/Developer/Xcode/DerivedData/KaMPKitiOS-czccbxoiggfeplculcfguxucvfdv/Build/Intermediates.noindex/Pods.build/Debug-iphoneos/shared.build/Objects-normal, CORRESPONDING_SIMULATOR_PLATFORM_DIR=/Applications/Xcode-beta.app/Contents/Developer/Platforms/iPhoneSimulator.platform, TEMP_ROOT=/Users/benjaminlim/Library/Developer/Xcode/DerivedData/KaMPKitiOS-czccbxoiggfeplculcfguxucvfdv/Build/Intermediates.noindex, KASAN_DEFAULT_CFLAGS=-DKASAN=1 -fsanitize=address -mllvm -asan-globals-live-support -mllvm -asan-force-dynamic-shadow, SCRIPT_OUTPUT_FILE_COUNT=0, EXCLUDED_RECURSIVE_SEARCH_PATH_SUBDIRECTORIES=*.nib *.lproj *.framework *.gch *.xcode* *.xcassets (*) .DS_Store CVS .svn .git .hg *.pbproj *.pbxproj, PATH_PREFIXES_EXCLUDED_FROM_HEADER_DEPENDENCIES=/usr/include /usr/local/include /System/Library/Frameworks /System/Library/PrivateFrameworks /Applications/Xcode-beta.app/Contents/Developer/Headers /Applications/Xcode-beta.app/Contents/Developer/SDKs /Applications/Xcode-beta.app/Contents/Developer/Platforms, CHOWN=/usr/sbin/chown, CLANG_WARN_COMMA=YES, DEVELOPER_LIBRARY_DIR=/Applications/Xcode-beta.app/Contents/Developer/Library, COMPOSITE_SDK_DIRS=/Users/benjaminlim/Library/Developer/Xcode/DerivedData/KaMPKitiOS-czccbxoiggfeplculcfguxucvfdv/Build/Intermediates.noindex/CompositeSDKs, CLANG_WARN_UNREACHABLE_CODE=YES, CLANG_ANALYZER_NONNULL=YES, SYSTEM_DEVELOPER_TOOLS_DOC_DIR=/Applications/Xcode-beta.app/Contents/Developer/ADC Reference Library/documentation/DeveloperTools, COPY_RESOURCES_FROM_STATIC_FRAMEWORKS=YES, BUILD_COMPONENTS=headers build, MallocNanoZone=0, BUNDLE_PUBLIC_HEADERS_FOLDER_PATH=Headers, DEVELOPER_BIN_DIR=/Applications/Xcode-beta.app/Contents/Developer/usr/bin, MAC_OS_X_VERSION_MAJOR=101500, APPLICATION_EXTENSION_API_ONLY=NO, CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION=YES_AGGRESSIVE, CLANG_WARN_DOCUMENTATION_COMMENTS=YES, PROJECT_TEMP_DIR=/Users/benjaminlim/Library/Developer/Xcode/DerivedData/KaMPKitiOS-czccbxoiggfeplculcfguxucvfdv/Build/Intermediates.noindex/Pods.build, PLATFORM_PRODUCT_BUILD_VERSION=18A5332e, CLANG_WARN_EMPTY_BODY=YES, DERIVED_FILES_DIR=/Users/benjaminlim/Library/Developer/Xcode/DerivedData/KaMPKitiOS-czccbxoiggfeplculcfguxucvfdv/Build/Intermediates.noindex/Pods.build/Debug-iphoneos/shared.build/DerivedSources, CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF=YES, DEPLOYMENT_TARGET_CLANG_FLAG_PREFIX=-miphoneos-version-min=, SCAN_ALL_SOURCE_FILES_FOR_INCLUDES=NO, AD_HOC_CODE_SIGNING_ALLOWED=NO, CA_DEBUG_TRANSACTIONS=1, STRIP_INSTALLED_PRODUCT=NO, CODE_SIGN_CONTEXT_CLASS=XCiPhoneOSCodeSignContext, DEPLOYMENT_TARGET_LD_ENV_NAME=IPHONEOS_DEPLOYMENT_TARGET, SYSTEM_DEVELOPER_TOOLS=/Applications/Xcode-beta.app/Contents/Developer/Tools, SYSTEM_DEMOS_DIR=/Applications/Extras, MAC_OS_X_PRODUCT_BUILD_VERSION=19F101, INSTALL_DIR=/tmp/Pods.dst, SWIFT_VERSION=5.0, ENTITLEMENTS_DESTINATION=Signature, BUILT_PRODUCTS_DIR=/Users/benjaminlim/Library/Developer/Xcode/DerivedData/KaMPKitiOS-czccbxoiggfeplculcfguxucvfdv/Build/Products/Debug-iphoneos/shared, SOURCE_ROOT=/Users/benjaminlim/Desktop/gameface-kampkit/ios/Pods, CLANG_ENABLE_OBJC_ARC=YES, CHMOD=/bin/chmod, JIKES_DEFAULT_FLAGS=+E +OLDCSO, EMBEDDED_PROFILE_NAME=embedded.mobileprovision, SUPPORTS_MACCATALYST=YES, SDK_VERSION=14.0, DSTROOT=/tmp/Pods.dst, ARCHS_STANDARD_64_BIT=arm64, PROJECT_TEMP_ROOT=/Users/benjaminlim/Library/Developer/Xcode/DerivedData/KaMPKitiOS-czccbxoiggfeplculcfguxucvfdv/Build/Intermediates.noindex, STRIP_STYLE=all, BUILD_ACTIVE_RESOURCES_ONLY=YES, GID=20, SET_FILE_MODE_OWNER_GROUP=NO, JAVA_MAIN_CLASS_20985=org.gradle.wrapper.GradleWrapperMain, NATIVE_ARCH_ACTUAL=x86_64, SEPARATE_STRIP=NO, EMBEDDED_CONTENT_CONTAINS_SWIFT=NO, PRODUCT_NAME=shared, PLATFORM_DEVELOPER_LIBRARY_DIR=/Applications/Xcode-beta.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/Library, TMPDIR=/var/folders/8q/7x399f1924g4hq82xs2kzb1r0000gn/T/, SYSTEM_DEVELOPER_DEMOS_DIR=/Applications/Xcode-beta.app/Contents/Developer/Applications/Utilities/Built Examples, PODS_ROOT=/Users/benjaminlim/Desktop/gameface-kampkit/ios/Pods, ASSETCATALOG_FILTER_FOR_DEVICE_OS_VERSION=13.5.1, LD_MAP_FILE_PATH=/Users/benjaminlim/Library/Developer/Xcode/DerivedData/KaMPKitiOS-czccbxoiggfeplculcfguxucvfdv/Build/Intermediates.noindex/Pods.build/Debug-iphoneos/shared.build/shared-LinkMap-normal-undefined_arch.txt, GCC_VERSION=com.apple.compilers.llvm.clang.1_0, PKGINFO_FILE_PATH=/Users/benjaminlim/Library/Developer/Xcode/DerivedData/KaMPKitiOS-czccbxoiggfeplculcfguxucvfdv/Build/Intermediates.noindex/Pods.build/Debug-iphoneos/shared.build/PkgInfo, JAVA_USE_DEPENDENCIES=YES, SWIFT_ACTIVE_COMPILATION_CONDITIONS=DEBUG, COMPILER_INDEX_STORE_ENABLE=Default, SYSTEM_DEVELOPER_GRAPHICS_TOOLS_DIR=/Applications/Xcode-beta.app/Contents/Developer/Applications/Graphics Tools, DWARF_DSYM_FOLDER_PATH=/Users/benjaminlim/Library/Developer/Xcode/DerivedData/KaMPKitiOS-czccbxoiggfeplculcfguxucvfdv/Build/Products/Debug-iphoneos/shared, PROJECT_NAME=Pods, HIDE_BITCODE_SYMBOLS=YES, DEPLOYMENT_TARGET_SETTING_NAME=IPHONEOS_DEPLOYMENT_TARGET, ALWAYS_SEARCH_USER_PATHS=NO, LD_DEPENDENCY_INFO_FILE=/Users/benjaminlim/Library/Developer/Xcode/DerivedData/KaMPKitiOS-czccbxoiggfeplculcfguxucvfdv/Build/Intermediates.noindex/Pods.build/Debug-iphoneos/shared.build/Objects-normal/undefined_arch/shared_dependency_info.dat, PLIST_FILE_OUTPUT_FORMAT=binary, PRODUCT_MODULE_NAME=shared, JAVA_COMPILER=/usr/bin/javac, DEFAULT_COMPILER=com.apple.compilers.llvm.clang.1_0, FRAMEWORK_VERSION=A, SDK_VERSION_ACTUAL=140000, USER=benjaminlim, CLANG_WARN_UNGUARDED_AVAILABILITY=YES_AGGRESSIVE, SWIFT_RESPONSE_FILE_PATH_normal_arm64=/Users/benjaminlim/Library/Developer/Xcode/DerivedData/KaMPKitiOS-czccbxoiggfeplculcfguxucvfdv/Build/Intermediates.noindex/Pods.build/Debug-iphoneos/shared.build/Objects-normal/arm64/shared.SwiftFileList, SSH_AUTH_SOCK=/private/tmp/com.apple.launchd.F4QgEU3E5a/Listeners, XCODE_PRODUCT_BUILD_VERSION=12A8169g, CLANG_WARN_RANGE_LOOP_ANALYSIS=YES, CACHE_ROOT=/var/folders/8q/7x399f1924g4hq82xs2kzb1r0000gn/C/com.apple.DeveloperTools/12.0-12A8169g/Xcode, BUNDLE_PRIVATE_HEADERS_FOLDER_PATH=PrivateHeaders}
10:15:17.018 [DEBUG] [org.gradle.launcher.daemon.server.SynchronizedDispatchConnection] thread 17: received class org.gradle.launcher.daemon.protocol.CloseInput
10:15:17.018 [DEBUG] [org.gradle.launcher.daemon.server.DefaultDaemonConnection] thread 17: Received IO message from client: org.gradle.launcher.daemon.protocol.CloseInput@203dc6e5
10:15:17.026 [DEBUG] [org.gradle.launcher.daemon.server.exec.LogToClient] About to start relaying all logs to the client via the connection.
10:15:17.026 [INFO] [org.gradle.launcher.daemon.server.exec.LogToClient] The client will now receive all logging from the daemon (pid: 21010). The daemon log file: /Users/benjaminlim/.gradle/daemon/5.6.4/daemon-21010.out.log
10:15:17.027 [INFO] [org.gradle.launcher.daemon.server.exec.LogAndCheckHealth] Starting build in new daemon [memory: 1.4 GB]
10:15:17.028 [INFO] [org.gradle.launcher.daemon.server.exec.ForwardClientInput] Closing daemon's stdin at end of input.
10:15:17.028 [INFO] [org.gradle.launcher.daemon.server.exec.ForwardClientInput] The daemon will no longer process any standard input.
10:15:17.031 [DEBUG] [org.gradle.launcher.daemon.server.exec.ExecuteBuild] The daemon has started executing the build.
10:15:17.032 [DEBUG] [org.gradle.launcher.daemon.server.exec.ExecuteBuild] Executing build with daemon context: DefaultDaemonContext[uid=b057873f-4c43-4a55-9b45-3416bc747aa8,javaHome=/Library/Java/JavaVirtualMachines/jdk1.8.0_261.jdk/Contents/Home,daemonRegistryDir=/Users/benjaminlim/.gradle/daemon,pid=21010,idleTimeout=10800000,priority=NORMAL,daemonOpts=-Xmx1536m,-Dfile.encoding=UTF-8,-Duser.country=AU,-Duser.language=en,-Duser.variant]
Kotlin Multiplatform Projects are an experimental feature.
e: Could not find "/Users/benjaminlim/.gradle/caches/modules-2/files-2.1/org.jetbrains.kotlinx/kotlinx-datetime-iosarm64/0.1.0/f56a0f1b22d3be80644aaf5f6de94fc17efc097d/kotlinx-datetime.klib" in [/Users/benjaminlim/Desktop/gameface-kampkit/ios/Pods, /Users/benjaminlim/.konan/klib, /Users/benjaminlim/.konan/kotlin-native-macos-1.3.72/klib/common, /Users/benjaminlim/.konan/kotlin-native-macos-1.3.72/klib/platform/ios_arm64].
Daemon vm is shutting down... The daemon has exited normally or was terminated in response to a user interrupt.
----- End of the daemon log -----


FAILURE: Build failed with an exception.

* What went wrong:
Gradle build daemon disappeared unexpectedly (it may have been killed or may have crashed)

* Try:
Run with --stacktrace option to get the stack trace. Run with --info or --debug option to get more log output. Run with --scan to get full insights.

* Get more help at https://help.gradle.org
> Task :shared:compileKotlinIos
Command PhaseScriptExecution failed with a nonzero exit code

Add non-throwing LocalDate(Time) construction & parsing

There should be null-returning variants for creating LocalDate(Time) instances. It shouldn't be necessary to catch an exception. This is especially useful when creating instances from user input.

val date = runCatching { LocalDate(userInput.year, userInput.month, userInput.day) }.getOrNull()

Also:

  • Instant.parse(โ€ฆ)
  • TimeZone.of(โ€ฆ)
  • etc.

Just like all similar stdlib functions have โ€ฆOrNull variants.

https://elizarov.medium.com/kotlin-and-exceptions-8062f589d07

TimeZone.SYSTEM encourages static dependency

Following on from the Instant.now() static dependency on the system clock, TimeZone.SYSTEM has a similar static dependency on the system.

Would it make sense to put this as an instance member on Clock as well? That's how (one of) our clock abstractions exposes it.

Without this you'll have the ability to control time in places like tests. Anyone calling into TimeZone.SYSTEM and combining it with an instant from a fake clock will produce a time in the hosts zone rather than a stable zone likely producing flaky tests.

Clock.System.now() on Android API 24

Hello!
How can I get the current system time on an Andoid device with API lower than 26 using this library?
When i use localDateTime.month.getDisplayName() I get a warning that the call requires API level 26, but with Clock.System.now () there is no warning

Could not find org.jetbrains.kotlinx:kotlinx-datetime:0.1.0 (in default repositories)

I wanna run a Kotlin Multiplatform Mobile project using this library. After configuring the gradle script like shown in the screenshot, I get the following error:

Execution failed for task ':androidApp:checkDebugAarMetadata'.
> Could not resolve all files for configuration ':androidApp:debugRuntimeClasspath'.
   > Could not find org.jetbrains.kotlinx:kotlinx-datetime:0.1.0.
     Searched in the following locations:
       - https://plugins.gradle.org/m2/org/jetbrains/kotlinx/kotlinx-datetime/0.1.0/kotlinx-datetime-0.1.0.pom
       - https://dl.google.com/dl/android/maven2/org/jetbrains/kotlinx/kotlinx-datetime/0.1.0/kotlinx-datetime-0.1.0.pom
       - https://jcenter.bintray.com/org/jetbrains/kotlinx/kotlinx-datetime/0.1.0/kotlinx-datetime-0.1.0.pom
       - https://repo.maven.apache.org/maven2/org/jetbrains/kotlinx/kotlinx-datetime/0.1.0/kotlinx-datetime-0.1.0.pom
     Required by:
         project :androidApp > project :shared

Possible solution:
 - Declare repository providing the artifact, see the documentation at https://docs.gradle.org/current/userguide/declaring_repositories.html

Only after adding the custom maven repo to the build gradle file inside the android sub project, the dependency is found. I don't think that this is right.

image

NoClassDefFoundError Ljava/time/ZoneOffset

On specific phone - zebra tc25 get a runtime exception. Stacktrace ->

java.lang.ClassNotFoundException: Didn't find class "java.time.ZoneOffset" on path: DexPathList[[zip file "/data/app/com.p1ng2win.gabiapplication-2/base.apk"],nativeLibraryDirectories=[/data/app/com.p1ng2win.gabiapplication-2/lib/arm64, /data/app/com.p1ng2win.gabiapplication-2/base.apk!/lib/arm64-v8a, /system/lib64, /vendor/lib64]]
    at dalvik.system.BaseDexClassLoader.findClass(BaseDexClassLoader.java:56)
    at java.lang.ClassLoader.loadClass(ClassLoader.java:380)
    at java.lang.ClassLoader.loadClass(ClassLoader.java:312)
    at kotlinx.datetime.TimeZone.<clinit>(TimeZoneJvm.kt:32)
    at com.p1ng2win.gabiapplication.framework.stuff.exts.KotlinExtensionsKt.systemLocalDate(KotlinExtensions.kt:38)
    at com.p1ng2win.gabiapplication.framework.model.WorkerVM$onChangeFIO$1.invokeSuspend(WorkerVM.kt:38)
    at kotlin.coroutines.jvm.internal.BaseContinuationImpl.resumeWith(ContinuationImpl.kt:33)
    at kotlinx.coroutines.DispatchedContinuationKt.resumeCancellableWith(DispatchedContinuation.kt:330)
    at kotlinx.coroutines.intrinsics.CancellableKt.startCoroutineCancellable(Cancellable.kt:26)
    at kotlinx.coroutines.CoroutineStart.invoke(CoroutineStart.kt:109)
    at kotlinx.coroutines.AbstractCoroutine.start(AbstractCoroutine.kt:158)
    at kotlinx.coroutines.BuildersKt__Builders_commonKt.launch(Builders.common.kt:54)
    at kotlinx.coroutines.BuildersKt.launch
    at kotlinx.coroutines.BuildersKt__Builders_commonKt.launch$default(Builders.common.kt:47)
    at kotlinx.coroutines.BuildersKt.launch$default
    at com.p1ng2win.gabiapplication.framework.model.WorkerVM.onChangeFIO(WorkerVM.kt:30)
    at com.p1ng2win.gabiapplication.ui.fragments.actions.init.employee.EmployeeFragment$initView$1.invoke(EmployeeFragment.kt:54)
    at com.p1ng2win.gabiapplication.ui.fragments.actions.init.employee.EmployeeFragment$initView$1.invoke(EmployeeFragment.kt:25)
    at com.p1ng2win.gabiapplication.ui.adapters.EmployeeAdapter$employeeDelegate$1$1.onClick(EmployeeAdapter.kt:23)
    at android.view.View.performClick(View.java:5637)
    at com.google.android.material.button.MaterialButton.performClick(MaterialButton.java:992)
    at android.view.View$PerformClick.run(View.java:22433)
    at android.os.Handler.handleCallback(Handler.java:751)
    at android.os.Handler.dispatchMessage(Handler.java:95)
    at android.os.Looper.loop(Looper.java:154)
    at android.app.ActivityThread.main(ActivityThread.java:6123)
    at java.lang.reflect.Method.invoke(Method.java)
    at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:889)
    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:779)
java.lang.NoClassDefFoundError: Failed resolution of: Ljava/time/ZoneOffset;
    at kotlinx.datetime.TimeZone.<clinit>(TimeZoneJvm.kt:32)
    at com.p1ng2win.gabiapplication.framework.stuff.exts.KotlinExtensionsKt.systemLocalDate(KotlinExtensions.kt:38)
    at com.p1ng2win.gabiapplication.framework.model.WorkerVM$onChangeFIO$1.invokeSuspend(WorkerVM.kt:38)
    at kotlin.coroutines.jvm.internal.BaseContinuationImpl.resumeWith(ContinuationImpl.kt:33)
    at kotlinx.coroutines.DispatchedContinuationKt.resumeCancellableWith(DispatchedContinuation.kt:330)
    at kotlinx.coroutines.intrinsics.CancellableKt.startCoroutineCancellable(Cancellable.kt:26)
    at kotlinx.coroutines.CoroutineStart.invoke(CoroutineStart.kt:109)
    at kotlinx.coroutines.AbstractCoroutine.start(AbstractCoroutine.kt:158)
    at kotlinx.coroutines.BuildersKt__Builders_commonKt.launch(Builders.common.kt:54)
    at kotlinx.coroutines.BuildersKt.launch
    at kotlinx.coroutines.BuildersKt__Builders_commonKt.launch$default(Builders.common.kt:47)
    at kotlinx.coroutines.BuildersKt.launch$default
    at com.p1ng2win.gabiapplication.framework.model.WorkerVM.onChangeFIO(WorkerVM.kt:30)
    at com.p1ng2win.gabiapplication.ui.fragments.actions.init.employee.EmployeeFragment$initView$1.invoke(EmployeeFragment.kt:54)
    at com.p1ng2win.gabiapplication.ui.fragments.actions.init.employee.EmployeeFragment$initView$1.invoke(EmployeeFragment.kt:25)
    at com.p1ng2win.gabiapplication.ui.adapters.EmployeeAdapter$employeeDelegate$1$1.onClick(EmployeeAdapter.kt:23)
    at android.view.View.performClick(View.java:5637)
    at com.google.android.material.button.MaterialButton.performClick(MaterialButton.java:992)
    at android.view.View$PerformClick.run(View.java:22433)
    at android.os.Handler.handleCallback(Handler.java:751)
    at android.os.Handler.dispatchMessage(Handler.java:95)
    at android.os.Looper.loop(Looper.java:154)
    at android.app.ActivityThread.main(ActivityThread.java:6123)
    at java.lang.reflect.Method.invoke(Method.java)
    at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:889)
    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:779)

systemLocalDate ext - >

fun systemLocalDate(): LocalDate =
    Clock.System.todayAt(TimeZone.currentSystemDefault())

Instant.until(Instant, DateTimeUnit.TimeBased) and until(Instant, DateTimeUnit, TimeZone) maybe shouldn't be overloads

The following two APIs on Instant aren't really overloads:

  • until(Instant, DateTimeUnit.TimeBased)
  • until(Instant, DateTimeUnit, TimeZone)

One takes timezones into account and the other one doesn't. That doesn't seem like a great pair of APIs to be overloads of one another. Perhaps the time-based one should have a longer, scarier name to discourage use? (e.g., timeUntil() or timeUnitsUntil())

Same issue for the analogous plus() and minus() overloads on Instant.

Clock.System.now() crashes on arm32/iOS9

When calling the method Clock.System.now() on an iPod 5 (arm32/iOS9) the app crashes as if it posix_clock_gettime is not available on that device.
image

Other methods like determining the timezone of the device work fine.

The current workaround to this problem is to have an expect/actual fun to get the system time. The iOS version would be to use NSDate() to get the system time.

NoClassDefFoundError: kotlinx/datetime/Clock$System

Got this error on my kotlin api with Ktor


Exception in thread "main" java.lang.reflect.InvocationTargetException
        at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
        at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
        at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
        at java.base/java.lang.reflect.Method.invoke(Method.java:566)
        at kotlin.reflect.jvm.internal.calls.CallerImpl$Method.callMethod(CallerImpl.kt:97)
        at kotlin.reflect.jvm.internal.calls.CallerImpl$Method$Static.call(CallerImpl.kt:106)
        at kotlin.reflect.jvm.internal.KCallableImpl.call(KCallableImpl.kt:106)
        at kotlin.reflect.jvm.internal.KCallableImpl.callDefaultMethod$kotlin_reflection(KCallableImpl.kt:152)
        at kotlin.reflect.jvm.internal.KCallableImpl.callBy(KCallableImpl.kt:110)
        at io.ktor.server.engine.ApplicationEngineEnvironmentReloading.callFunctionWithInjection(ApplicationEngineEnvironmentReloading.kt:384)
        at io.ktor.server.engine.ApplicationEngineEnvironmentReloading.executeModuleFunction(ApplicationEngineEnvironmentReloading.kt:330)
        at io.ktor.server.engine.ApplicationEngineEnvironmentReloading.access$executeModuleFunction(ApplicationEngineEnvironmentReloading.kt:33)
        at io.ktor.server.engine.ApplicationEngineEnvironmentReloading$instantiateAndConfigureApplication$1$$special$$inlined$forEach$lambda$1.invoke(ApplicationEngineEnvironmentReloading.kt:275)
        at io.ktor.server.engine.ApplicationEngineEnvironmentReloading$instantiateAndConfigureApplication$1$$special$$inlined$forEach$lambda$1.invoke(ApplicationEngineEnvironmentReloading.kt:33)
        at io.ktor.server.engine.ApplicationEngineEnvironmentReloading.avoidingDoubleStartupFor(ApplicationEngineEnvironmentReloading.kt:310)
        at io.ktor.server.engine.ApplicationEngineEnvironmentReloading.access$avoidingDoubleStartupFor(ApplicationEngineEnvironmentReloading.kt:33)        at io.ktor.server.engine.ApplicationEngineEnvironmentReloading$instantiateAndConfigureApplication$1.invoke(ApplicationEngineEnvironmentReloading.kt:274)
        at io.ktor.server.engine.ApplicationEngineEnvironmentReloading$instantiateAndConfigureApplication$1.invoke(ApplicationEngineEnvironmentReloading.kt:33)
        at io.ktor.server.engine.ApplicationEngineEnvironmentReloading.avoidingDoubleStartup(ApplicationEngineEnvironmentReloading.kt:290)
        at io.ktor.server.engine.ApplicationEngineEnvironmentReloading.instantiateAndConfigureApplication(ApplicationEngineEnvironmentReloading.kt:272)
        at io.ktor.server.engine.ApplicationEngineEnvironmentReloading.createApplication(ApplicationEngineEnvironmentReloading.kt:125)
        at io.ktor.server.engine.ApplicationEngineEnvironmentReloading.start(ApplicationEngineEnvironmentReloading.kt:245)
        at io.ktor.server.netty.NettyApplicationEngine.start(NettyApplicationEngine.kt:126)
        at io.ktor.server.netty.EngineMain.main(EngineMain.kt:26)
Caused by: java.lang.NoClassDefFoundError: kotlinx/datetime/Clock$System
        at com.p1ng2win.stuff.ExtensionsKt.DateTimeUTC(Extensions.kt:34)
        at com.p1ng2win.model.stuff.MyLogger.writeIntoLogs(MyLogger.kt:64)
        at com.p1ng2win.model.stuff.MyLogger.logAny(MyLogger.kt:46)
        at com.p1ng2win.model.stuff.MyLogger.logAny$default(MyLogger.kt:42)
        at com.p1ng2win.ApplicationKt.mainModule(Application.kt:97)
        ... 24 more
Caused by: java.lang.ClassNotFoundException: kotlinx.datetime.Clock$System
        at java.base/jdk.internal.loader.BuiltinClassLoader.loadClass(BuiltinClassLoader.java:581)
        at java.base/jdk.internal.loader.ClassLoaders$AppClassLoader.loadClass(ClassLoaders.java:178)
        at java.base/java.lang.ClassLoader.loadClass(ClassLoader.java:521)
        ... 29 more

set sourceCompatibility and targetCompatibility

sourceCompatibility = 1.8
targetCompatibility = 1.8

Could this be due to apiVersion?


configure([compileKotlin, compileTestKotlin]) {
    kotlinOptions {
        jvmTarget = "1.8"
        apiVersion = "1.3"
    }
}

Simplify LocalDate(Time) constructor parameter names

The parameter names are very weird for day-to-day use:

LocalDateTime(year = 2021, monthNumber = 1, dayOfMonth = 1, hour = 12)

I don't care that month is a number. That's what we have a type system for.
OfMonth for day is also redundant as that's obvious from the context.

public constructor(year: Int, monthNumber: Int, dayOfMonth: Int, hour: Int, minute: Int, second: Int = 0, nanosecond: Int = 0)

Publish on mavenCentral

I know it's planned as currently written in the README, but I'd like to know when this happens, so I'm creating this issue that I hope will be closed when it's up there ๐Ÿ™‚ .

Instant parsing not working correctly on JS

Code like "2019-10-28T14:00:00+01:00".toInstant() works ok under JVM, but unfortunately not under JS.
This is caused by js-joda problem where Instant cannot use +01:00 offsets (only Zworks here) and causes

> var Instant = require("@js-joda/core").Instant;
undefined
> Instant.parse('2019-10-28T14:00:00+01:00')
Uncaught:
DateTimeParseException: Text '2019-10-28T14:00:00+01:00' could not be parsed at index 19: 2019-10-28T14:00:00+01:00, at index: 19
    at DateTimeFormatter._parseToBuilder (/Users/jakub.gwozdz/tmp/node_modules/@js-joda/core/dist/js-joda.js:6972:19)
    at DateTimeFormatter.parse2 (/Users/jakub.gwozdz/tmp/node_modules/@js-joda/core/dist/js-joda.js:6933:30)
    at DateTimeFormatter.parse (/Users/jakub.gwozdz/tmp/node_modules/@js-joda/core/dist/js-joda.js:6910:23)
    at Function.parse (/Users/jakub.gwozdz/tmp/node_modules/@js-joda/core/dist/js-joda.js:12368:46) {
  parsedString: [Function],
  errorIndex: [Function],
  toString: [Function]
}

solution would be going through ZonedDateTime:

> ZonedDateTime.parse('2019-10-28T14:00:00+01:00').toInstant()
Instant { _seconds: 1572267600, _nanos: 0 }

Provide constructor for Instant class that takes a Double

Hello,
I really like using your project. I just miss one little feature:
could you provide a constructor for the Instant class that takes a timestamp of type Double (milliseconds since 1 January 1970 UTC)?

Reason: we try to avoid creating objects in our multi-platform project wherever possible, but using Long for timestamps results in object creation. A Double value can be directly mapped to a JavaScript Number value. It also feels more natural to what the JavaScript Date class does.

Thanks in advance!

Allow to parse instants with UTC offsets other than Z

The README states that e.g. Instant only has ISO-8601 support but i think it only has partial support.

Instant.parse("2020-09-21T09:12:47Z") works as expected but Instant.parse("2020-09-21T09:12:47+00:00") throws a DateTimeParseException

Some implementation details are dictated by Kotlin/Native shortcomings

  • In several places, x in A..B is replaced with the non-idiomatic x >= A && x <= B. This is due to the fact that Kotlin/Native does not yet optimize such constructs outside of for-loops. In particular, in LocalTime#ofSecondOfDay about half the time of the function execution was spent in argument validity checks, allocating several objects in the meantime. https://youtrack.jetbrains.com/issue/KT-38787
  • Parsers are not singleton objects but are instead functions that return newly-constructed parsers. This is done to sidestep a bug that led to an unchecked null value dereferencing as a result of wrong initialization order of values: parser A, referencing parser B, was being initialized before B, which led to it dereferencing a null value.

Add an OffsetDateTime type

it would be quite good if there was a type (maybe let's call it OffsetDateTime to distinguish it from a possible ZonedDateTime) that can represent a LocalDateTime and TimeZone ZoneOffset together. This is especially useful for parsing RFC3339 compatible strings in common code (e.g. OpenAPITools/openapi-generator#7353 (comment)).

It can easily be accomplished without any platform-specific code, I've already drafted a small example with should be enough for most use-cases (but uses some custom parsing logic, which will only work for RFC3339 compatible strings)

Example
package com.example

import kotlinx.datetime.*
import kotlin.jvm.JvmStatic

/**
 * Represents a [LocalDateTime] and the respective [ZoneOffset] of it.
 */
public class OffsetDateTime private constructor(public val dateTime: LocalDateTime, public val offset: ZoneOffset) {
    override fun toString(): String {
        return if (offset.totalSeconds == 0) {
            "${dateTime}Z"
        } else {
            "$dateTime$offset"
        }
    }

    /**
     * Converts the [OffsetDateTime] to an [Instant]. This looses the [ZoneOffset] information, because the date and time
     * is converted to UTC in the process.
     */
    public fun toInstant(): Instant = dateTime.toInstant(offset)

    /**
     * Returns a new [OffsetDateTime] with the given [TimeZone].
     */
    public fun atZoneSameInstant(newTimeZone: TimeZone): OffsetDateTime {
        val instant = dateTime.toInstant(offset)
        val newDateTime = instant.toLocalDateTime(newTimeZone)
        return OffsetDateTime(newDateTime, newTimeZone.offsetAt(instant))
    }

    public companion object {
        private val zoneRegex by lazy {
            Regex("""[+\-][0-9]{2}:[0-9]{2}""")
        }

        /**
         * Parses an [OffsetDateTime] from a RFC3339 compatible string.
         */
        @JvmStatic
        public fun parse(string: String): OffsetDateTime = when {
            string.contains('Z') -> OffsetDateTime(
                LocalDateTime.parse(string.substringBefore('Z')),
                TimeZone.UTC.offsetAt(Instant.fromEpochMilliseconds(0)),
            )
            string.contains('z') -> OffsetDateTime(
                LocalDateTime.parse(string.substringBefore('z')),
                TimeZone.UTC.offsetAt(Instant.fromEpochMilliseconds(0)),
            )
            zoneRegex.matches(string) -> {
                val dateTime = LocalDateTime.parse(string.substring(0, string.length - 6))
                val tz = TimeZone.of(string.substring(string.length - 6))
                val instant = dateTime.toInstant(tz)
                val offset = tz.offsetAt(instant)
                OffsetDateTime(
                    dateTime,
                    offset,
                )
            }
            else -> throw IllegalArgumentException("Date \"$string\" is not RFC3339 compatible")
        }

        /**
         * Creates an [OffsetDateTime] from an [Instant] in a given [TimeZone] ([TimeZone.UTC] by default).
         */
        @JvmStatic
        public fun ofInstant(instant: Instant, offset: TimeZone = TimeZone.UTC): OffsetDateTime = OffsetDateTime(
            instant.toLocalDateTime(offset),
            offset.offsetAt(instant),
        )

        /**
         *
         */
        @JvmStatic
        public fun of(dateTime: LocalDateTime, offset: ZoneOffset): OffsetDateTime = OffsetDateTime(dateTime, offset)
    }
}

Can't compile linkDebugFrameworkIosX.

Error while I try to do it:
Could not find ".gradle/caches/modules-2/files-2.1/org.jetbrains.kotlinx/kotlinx-datetime-iosx64/0.1.0/7f8408e9d3a4a1bdd33be41f3acc52008b52fc57/kotlinx-datetime.klib".

Invalid record (Producer: 'LLVM8.0.0svn' Reader: 'LLVM APPLE_1_1200.0.32.21_0')

I have it integrated correctly in my Kotlin Multiplatform project, and it will work fine for my android app. However, when I go to build my IOS app, I get this failure to build. Had hoped this was related to the apple developer tools and that the recent Xcode update would fix it, but problem persists.

I can change nothing else, even have import kotlinx.datetime.LocalDateTime in files, and both my android and iOS apps will run. As soon as I add a LocalDateTime field to a model, the android app will still work, but my iOS app won't compile.

Seems like a native Kotlin date time lib is essential, not sure why this is so new. I saw a commit a while back for an IOS crash fix, and think this is likely due to older compiler tools used when the last tag was made. When do we get a 0.1.1? Is this project still active or is there something else we can be using?

Instant.minus functions missing

I expected these to be available, since the plus functions are:

Instant.minus(period: DateTimePeriod, timeZone: TimeZone): Instant
Instant.minus(unit: DateTimeUnit, timeZone: TimeZone): Instant
Instant.minus(value: Long, unit: DateTimeUnit, timeZone: TimeZone): Instant

Issue including the library in kotlinjs project using gradle

I get this error in build
Could not determine the dependencies of task ':packageJson'.

Could not resolve all dependencies for configuration ':npm'.
Could not resolve org.jetbrains.kotlinx:kotlinx-datetime:0.1.0.
Required by:
project :
> Cannot choose between the following variants of org.jetbrains.kotlinx:kotlinx-datetime:0.1.0:
- jsIr-runtime
- jsLegacy-runtime
All of them match the consumer attributes:
- Variant 'jsIr-runtime' capability org.jetbrains.kotlinx:kotlinx-datetime:0.1.0:
- Unmatched attributes:
- Found org.gradle.status 'release' but wasn't required.
- Found org.jetbrains.kotlin.js.compiler 'ir' but wasn't required.
- Compatible attributes:
- Required org.gradle.usage 'kotlin-runtime' and found compatible value 'kotlin-runtime'.
- Required org.jetbrains.kotlin.platform.type 'js' and found compatible value 'js'.
- Variant 'jsLegacy-runtime' capability org.jetbrains.kotlinx:kotlinx-datetime:0.1.0:
- Unmatched attributes:
- Found org.gradle.status 'release' but wasn't required.
- Found org.jetbrains.kotlin.js.compiler 'legacy' but wasn't required.
- Compatible attributes:
- Required org.gradle.usage 'kotlin-runtime' and found compatible value 'kotlin-runtime'.
- Required org.jetbrains.kotlin.platform.type 'js' and found compatible value 'js'.

  • Try:
    Run with --stacktrace option to get the stack trace. Run with --info or --debug option to get more log output. Run with --scan to get full insights.

Compatibility Issue

LocalDateTime is only compatible for API 26 >. Does this support lower version of API < 26?

Wrong answers in some cases when adding date-based units to instants on Darwin and Windows

There is a rare scenario where the result may be off (usually by an hour) when the result of an addition to an Instant is in a time overlap and the source Instant has the lesser offset of the two possible in the overlap. Then, the overlap is resolved incorrectly.

val zone = TimeZone.of("Europe/Berlin")
val instant1 = LocalDateTime(2019, Month.OCTOBER, 27, 2, 59).toInstant(zone)
val instant2 = LocalDateTime(2019, Month.OCTOBER, 28, 2, 59).toInstant(zone)
val instant3 = instant1.minus(300, DateTimeUnit.DAY, zone)
val instant4 = instant1.minus(10, DateTimeUnit.MONTH, zone)
assertEquals(instant1.plus(DateTimeUnit.HOUR), instant2.plus(-1, DateTimeUnit.DAY, zone))
assertEquals(instant1.plus(DateTimeUnit.HOUR), instant3.plus(300, DateTimeUnit.DAY, zone))
assertEquals(instant1.plus(DateTimeUnit.HOUR), instant4.plus(10, DateTimeUnit.MONTH, zone))

All these assertions fail on Darwin and Windows but pass in the other implementations (JVM, Unix, JS).

Support RFC 822 datetime parsing

The RSS 2.0 specification denotes dates using RFC 822. My personal use case is that I'm writing a multiplatform RSS feed parser which would require date time parsing in this format.

I'm open to attempting a PR if the maintainers are interested.

 5.  DATE AND TIME SPECIFICATION
 
 5.1.  SYNTAX
 
 date-time   =  [ day "," ] date time        ; dd mm yy
                                             ;  hh:mm:ss zzz
 
 day         =  "Mon"  / "Tue" /  "Wed"  / "Thu"
             /  "Fri"  / "Sat" /  "Sun"
 
 date        =  1*2DIGIT month 2DIGIT        ; day month year
                                             ;  e.g. 20 Jun 82
 
 month       =  "Jan"  /  "Feb" /  "Mar"  /  "Apr"
             /  "May"  /  "Jun" /  "Jul"  /  "Aug"
             /  "Sep"  /  "Oct" /  "Nov"  /  "Dec"
 
 time        =  hour zone                    ; ANSI and Military
 
 hour        =  2DIGIT ":" 2DIGIT [":" 2DIGIT]
                                             ; 00:00:00 - 23:59:59
 
 zone        =  "UT"  / "GMT"                ; Universal Time
                                             ; North American : UT
             /  "EST" / "EDT"                ;  Eastern:  - 5/ - 4
             /  "CST" / "CDT"                ;  Central:  - 6/ - 5
             /  "MST" / "MDT"                ;  Mountain: - 7/ - 6
             /  "PST" / "PDT"                ;  Pacific:  - 8/ - 7
             /  1ALPHA                       ; Military: Z = UT;
                                             ;  A:-1; (J not used)
                                             ;  M:-12; N:+1; Y:+12
             / ( ("+" / "-") 4DIGIT )        ; Local differential
                                             ;  hours+min. (HHMM)
 
 5.2.  SEMANTICS
 
      If included, day-of-week must be the day implied by the date
 specification.
 
      Time zone may be indicated in several ways.  "UT" is Univer-
 sal  Time  (formerly called "Greenwich Mean Time"); "GMT" is per-
 mitted as a reference to Universal Time.  The  military  standard
 uses  a  single  character for each zone.  "Z" is Universal Time.
 "A" indicates one hour earlier, and "M" indicates 12  hours  ear-
 lier;  "N"  is  one  hour  later, and "Y" is 12 hours later.  The
 letter "J" is not used.  The other remaining two forms are  taken
 from ANSI standard X3.51-1975.  One allows explicit indication of
 the amount of offset from UT; the other uses  common  3-character
 strings for indicating time zones in North America.
 
 
 August 13, 1982              - 26 -                      RFC #822

Clock.System.now() crashes on Android 4.1 (API 16)

When calling the method Clock.System.now() on old Android 4.1 Jelly Bean (API 16) device/emulator the app throw java.lang.ExceptionInInitializerError:

09-21 13:13:27.111 2965-3003/com.softartdev.noteroom E/BaseViewModel$launch: java.lang.ExceptionInInitializerError
        at kotlinx.datetime.Clock$System.now(Clock.kt:17)

On the last Android versions works fine, checked on API 26~30.
The problem can be reproduce from source code of my pet-project:

fun createLocalDateTime(): LocalDateTime = Clock.System.now()
    .toLocalDateTime(TimeZone.currentSystemDefault())

Feature Request: Parse Instant from complex pattern

Use case:
I am working with timeseries data coming from

  • sensors of all sorts of types and vendors
  • business files (e.g. Excel exports in all kind of localizations and formats)
  • output from other systems in all sorts of formats.

From my experience the amount of variations is almost unlimited. Be it the separators (or sometimes the lack of), the order of the elements and also the potential absence of some parts (optionally millisecond fractions, optionally offsets minutes, ...). The requirement goes way beyond what you can usually represent as a string pattern with describing string like ("yyyy-MM-dd") which are fairly unreadable as well if you think about the amount of variables for non-standard-stuff (fractions, timezone hour, timezone minute, ...)

Reference solution:
Coming from Java, all of these formats can be easily represented using a DateTimeFormatter and described using a DateTimeFormatterBuilder. The DateTimeFormatter offers a lot of predefined ISO formats as well.

Side note: The DateTimeFormatter can be used for printing instants as well.

Summary:
A comprehensive datetime library needs utilities to allow import and export of date/time strings in all formats for compatibility with the rest of the world.

No support for linuxArm32Hfp as a target for Kotlin/Native

I notice that there's no support for ARM linux platforms in kotlinx-datetime (a common problem across K/N projects, sadly!).

Specifically, I am writing for the Raspberry Pi (linuxArm32Hfp) and it's not listed as a valid target. All I've found are:

kotlinx-datetime-iosarm32/
kotlinx-datetime-iosarm64/
kotlinx-datetime-iosx64/
kotlinx-datetime-js/
kotlinx-datetime-jvm/
kotlinx-datetime-linuxx64/
kotlinx-datetime-macosx64/
kotlinx-datetime-metadata/
kotlinx-datetime-mingwx64/
kotlinx-datetime-tvosarm64/
kotlinx-datetime-tvosx64/
kotlinx-datetime-watchosarm32/
kotlinx-datetime-watchosarm64/
kotlinx-datetime-watchosx86/
kotlinx-datetime/

Are there likely to be any major challenges in just duplicating the codebase from kotlinx-datetime-linuxx64 and recompiling? Is that something I could help with?

Add support for parsing offsets

Unless I'm missing something, there isn't currently any way to parse a datetime string with an offset.

"2020-08-20T12:00:00-05:00".toInstant()
kotlinx.datetime.DateTimeFormatException: java.time.format.DateTimeParseException: Text '2020-08-20T12:00:00-05:00' could not be parsed at index 19

Can't download the dependency

When I add the dependency to my KMM app, sync the project and run the app, I get the following error message:

Execution failed for task ':androidApp:checkXXXDebugAarMetadata'.
> Could not resolve all files for configuration ':androidApp:XXXDebugRuntimeClasspath'.
   > Could not find org.jetbrains.kotlinx:kotlinx-datetime:0.1.1.
     Searched in the following locations:
       - https://plugins.gradle.org/m2/org/jetbrains/kotlinx/kotlinx-datetime/0.1.1/kotlinx-datetime-0.1.1.pom
       - https://dl.google.com/dl/android/maven2/org/jetbrains/kotlinx/kotlinx-datetime/0.1.1/kotlinx-datetime-0.1.1.pom
       - https://jcenter.bintray.com/org/jetbrains/kotlinx/kotlinx-datetime/0.1.1/kotlinx-datetime-0.1.1.pom
       - https://repo.maven.apache.org/maven2/org/jetbrains/kotlinx/kotlinx-datetime/0.1.1/kotlinx-datetime-0.1.1.pom
     Required by:
         project :androidApp > project :shared

Possible solution:
 - Declare repository providing the artifact, see the documentation at https://docs.gradle.org/current/userguide/declaring_repositories.html

Consider deprecating the sub-date accessors on `DatePeriod`?

DatePeriod is defined as:

class DatePeriod(
        override val years: Int = 0,
        override val months: Int = 0,
        override val days: Int = 0
) : DateTimePeriod() {
    override val hours: Int get() = 0
    override val minutes: Int get() = 0
    override val seconds: Long get() = 0
    override val nanoseconds: Long get() = 0
}

It might be nice to document and deprecate the sub-date accessors, since calling them is almost wrong (they'll always return 0).

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.