{"id":13902273,"url":"https://github.com/sunny-chung/kdatetime-multiplatform","last_synced_at":"2025-06-30T13:36:38.573Z","repository":{"id":195377204,"uuid":"692666572","full_name":"sunny-chung/kdatetime-multiplatform","owner":"sunny-chung","description":"A Kotlin Multiplatform library to provide regular date-time functionality and interoperability needed with very minimal platform dependencies.","archived":false,"fork":false,"pushed_at":"2024-03-20T13:29:00.000Z","size":350,"stargazers_count":7,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"main","last_synced_at":"2024-04-18T03:23:01.965Z","etag":null,"topics":["android-library","datetime","ios","kotlin-js","kotlin-multiplatform","kotlin-multiplatform-library","macos"],"latest_commit_sha":null,"homepage":"https://sunny-chung.github.io/kdatetime-multiplatform/","language":"Kotlin","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/sunny-chung.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2023-09-17T07:49:50.000Z","updated_at":"2024-05-01T23:12:53.448Z","dependencies_parsed_at":"2023-09-17T18:00:58.405Z","dependency_job_id":"6cef717f-8a51-402a-948a-3a082d1193b8","html_url":"https://github.com/sunny-chung/kdatetime-multiplatform","commit_stats":null,"previous_names":["sunny-chung/kdatetime-multiplatform"],"tags_count":8,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/sunny-chung%2Fkdatetime-multiplatform","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/sunny-chung%2Fkdatetime-multiplatform/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/sunny-chung%2Fkdatetime-multiplatform/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/sunny-chung%2Fkdatetime-multiplatform/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/sunny-chung","download_url":"https://codeload.github.com/sunny-chung/kdatetime-multiplatform/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":247871503,"owners_count":21010054,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["android-library","datetime","ios","kotlin-js","kotlin-multiplatform","kotlin-multiplatform-library","macos"],"created_at":"2024-08-06T22:01:04.558Z","updated_at":"2025-04-08T15:32:43.127Z","avatar_url":"https://github.com/sunny-chung.png","language":"Kotlin","funding_links":[],"categories":["Kotlin"],"sub_categories":[],"readme":"# KDateTime Multiplatform\n\n![GitHub License](https://img.shields.io/github/license/sunny-chung/kdatetime-multiplatform)\n![Maven Central](https://img.shields.io/maven-central/v/io.github.sunny-chung/kdatetime-multiplatform)\n![Verification Test Status](https://github.com/sunny-chung/kdatetime-multiplatform/actions/workflows/run-test.yaml/badge.svg?branch=main)\n\n![Android](https://img.shields.io/badge/Android-blue)\n![JVM](https://img.shields.io/badge/JVM-blue)\n![js](https://img.shields.io/badge/js-blue)\n![iOS](https://img.shields.io/badge/iOS-blue)\n![macOS](https://img.shields.io/badge/macOS-blue)\n![watchOS](https://img.shields.io/badge/watchOS-blue)\n![tvOS](https://img.shields.io/badge/tvOS-blue)\n\nA Kotlin Multiplatform library to provide **regular date-time functionality needed with very minimal platform dependencies**. It means upgrading OS / platform SDK target versions or moving to another platform would not break your application. Same and consistent core API set is provided to all JVM, Apple, JS targets.\n\nComparing with the kotlinx one, this library additionally provides formatting and parsing from custom formatted string. As it has extremely few dependencies, it is very lightweight. The sum of all the artifacts among all the platforms, including source jars and javadocs, is less than 700 KB.\n\nThis library is going to be stable. Tests are executed against every push in the mainstream, and the status can be seen at the top of this README. All major features have been implemented, but suggestions and contributions are welcomed!\n\n## This README is DEPRECATED\n\nRead the [documentation website](https://sunny-chung.github.io/kdatetime-multiplatform/) instead. It is more organized and up-to-date.\n\n----------\n\n## TL;DR\n* [APIs](#apis)\n* [Examples](#examples)\n* [Getting Started](#getting-started)\n* [Limitations](#limitations)\n* [For Developers](#for-developers)\n\n# Supported Platforms\n- Android (Tested against compileSdk = 33, 34)\n- Non-Android JVM (macOS tested against 14.0 beta, Java 17; Windows and Linux untested)\n- JS (IR compiler only)\n- iOS (Tested against 16.4)\n- macOS Native (Tested against 14.0 beta)\n- watchOS (Tested against 10.0 beta)\n- tvOS (Tested against 17.0 beta)\n\n# APIs\n\nPublic classes / objects:\n- `KInstant` (single point of time)\n- `KZonedInstant` (single point of time + time zone offset)\n- `KZoneOffset` (time zone offset)\n- `KZonedDateTime` (date time + time zone offset)\n- `KDuration` (a date-time length)\n- `KFixedTimeUnit` (time unit)\n- `KDateTimeFormat` (format and parse dates and times)\n- `KGregorianCalendar` (conversion between timestamps and calendar dates)\n\nUnlike Java, there is no local date or local datetime class here. That creates lots of usage issues. `KZonedInstant` or `KZonedDateTime` can be used instead.\n\nThere is also no time zone but time zone offset at this moment.\n\nAll of these classes are **thread-safe**, **serializable** and **parcelable**.\n\nSupported custom format pattern symbols can be checked [here](src/commonMain/kotlin/com/sunnychung/lib/multiplatform/kdatetime/KDateTimeFormat.kt). It has some difference with Java APIs.\n\n# Examples\n\n## Now, Time Zone Offset, Formatting, Calendar, Parsing\n```kotlin\nval now = KInstant.now()\nprintln(now.toMilliseconds()) // 1694618242720\n\nval localZoneOffset = KZoneOffset.local()\nprintln(localZoneOffset.toDisplayString()) // +08:00\n\nval localDateTime = now.atZoneOffset(localZoneOffset) // or now.atLocalZoneOffset()\nprintln(localDateTime.format(\"yyyy-MM-dd'T'HH:mm:ss.lllZ\")) // 2023-09-13T23:17:22.720+08:00\nprintln(localDateTime.format(\"dd MMM yyyy h:mm:ss aa\")) // 13 Sep 2023 11:17:22 pm\n\nprintln(KZonedInstant.nowAtLocalZoneOffset()) // 2023-09-13T23:17:22.722+08:00\n\nval japanDateTime = now.atZoneOffset(KZoneOffset(9, 0))\nprintln(japanDateTime) // 2023-09-14T00:17:22.720+09:00\nprintln(now at KZoneOffset(9, 0)) // 2023-09-14T00:17:22.720+09:00\n\nval lastTrainTime = localDateTime.toKZonedDateTime().copy(hour = 23, minute = 10, second = 0, millisecond = 0)\nprintln(KDateTimeFormat.ISO8601_DATETIME.format(lastTrainTime.toKZonedInstant())) // 2023-09-13T23:10:00+08:00\n\nval parsedDateTime = KDateTimeFormat.ISO8601_DATETIME.parseToKZonedInstant(\"2023-09-10T17:18:53-07:00\")\nprintln(parsedDateTime.toMilliseconds()) // 1694391533000\n\nval duration1 = 95.seconds()\nprintln(duration1.format(\"m:ss\")) // 1:35\nprintln(duration1.format(\"m'm' s's'\")) // 1m 35s\n\nval dateTime = KInstant(1705677172000) // Friday, January 19, 2024 3:12:52 PM GMT\nval formatter = KDateTimeFormat(\"E\")\nprintln(formatter.format(dateTime)) // Fri\nformatter.weekDayNames = listOf(\"星期日\", \"星期一\", \"星期二\", \"星期三\", \"星期四\", \"星期五\", \"星期六\")\nprintln(formatter.format(dateTime)) // 星期五\nprintln(dateTime.format(\"yyyy-MM-dd HH:mm:ss (z)\")) // 2024-01-19 15:12:52 (+00:00)\n```\n\n## Conversions\nTime unit conversions.\n```kotlin\nval twoMinutes = 2.minutes()\nprintln(twoMinutes.toSeconds()) // 120\n```\n\n## Arithmetic, Comparison\n```kotlin\nval tomorrow = now + 1.days()\nprintln(KDateTimeFormat.ISO8601_DATETIME.format(tomorrow)) // 2023-09-14T15:17:22Z\n\nval duration2 = 1.minutes() + 35.seconds()\nprintln(duration2.format(\"mm:ss\")) // 01:35\n\nprintln(tomorrow.atZoneOffset(KZoneOffset(-7, 0)) \u003e now.atZoneOffset(KZoneOffset(8, 0))) // true\n\nval oneDay = tomorrow - now\nprintln(oneDay.toMilliseconds()) // 86400000\n\nval sortedInstants = listOf(1694618242720, 1694618242723, 1694618242721, 1694618242722)\n    .map { KInstant(it) }\n    .sorted()\nprintln(sortedInstants) // [2023-09-13T15:17:22.720Z, 2023-09-13T15:17:22.721Z, 2023-09-13T15:17:22.722Z, 2023-09-13T15:17:22.723Z]\n\nval zonedDateTime = KZonedDateTime(\n    year = 2023,\n    month = 10,\n    day = 4,\n    hour = 13,\n    minute = 8,\n    second = 40,\n    zoneOffset = KZoneOffset.parseFrom(\"+08:00\")\n)\nval zonedDateTime2 = zonedDateTime + duration2\nprintln(zonedDateTime2) // 2023-10-04T13:10:15.000+08:00\n\nprintln(10_000.milliseconds() \u003e 9.seconds()) // true\n\nval closedTimeRange = KInstant(1709975163000) .. KInstant(1709975173000)\nprintln(KZonedInstant(timestampMs = 1709975165000, zoneOffset = KZoneOffset(8, 0)) in closedTimeRange) // true\n\nval openTimeRange = KZonedInstant(1709975163000, KZoneOffset(1, 0)) ..\u003c KZonedInstant(1709975173000, KZoneOffset(1, 0))\nprintln(KInstant(timestampMs = 1709975165000) in openTimeRange) // true\n```\n\nTo use the `in` operator, manual importing an extension function is needed:\n```kotlin\nimport com.sunnychung.lib.multiplatform.kdatetime.extension.contains\n```\n\n## Serialization, Deserialization\nThis library supports `kotlinx.serialization` out of the box (except `KDuration`), to allow conversion between KDateTime classes and string from/to JSON, protobuf, etc.. Read [examples here](src/commonTest/kotlin/com/sunnychung/lib/multiplatform/kdatetime/SerializerTest.kt).\n\nBesides, an additional type `KInstantAsLong` is provided for converting between timestamp in milliseconds (`Long`) and `KInstant`.\n\n```kotlin\n@Serializable\n@AndroidParcelize\nclass TransitConnect : AndroidParcelable {\n    lateinit var summary: Summary\n\n    @Serializable\n    @AndroidParcelize\n    class Summary : WithDuration, AndroidParcelable {\n        override lateinit var startAt: KZonedInstant\n        override lateinit var endAt: KZonedInstant\n        var walkingSeconds: Long = -1\n        var waitingSeconds: Long = -1\n        var numOfTrips: Int = -1\n    }\n}\n```\n\n## Compatibility with platform-specific datetime APIs\n### From Kotlin side\n[iOS](src/darwinMain/kotlin/com/sunnychung/lib/multiplatform/kdatetime/KDateTime.kt),\n[JS](src/jsMain/kotlin/com/sunnychung/lib/multiplatform/kdatetime/JsPlatformDatetimeConversion.kt),\n[JVM](src/commonJvmMain/kotlin/com/sunnychung/lib/multiplatform/kdatetime/JvmPlatformDatetimeConversion.kt)\n\nFor example, for iOS targets:\n```kotlin\nval instant: KInstant = NSDate().toKInstant()\nval date: NSDate = instant.toNSDate()\n```\n\n### From native side\niOS\n```swift\nlet instant: KInstant = KInstant.companion.now() as KInstant\nlet iosDate: Date = instant.toNSDate()\nlet instant2: KInstant = KDateTimeKt.KInstantFrom(date: iosDate)\n```\n\n### For Android\nThe classes `KInstant`, `KZonedInstant`, `KZonedDateTime`, `KZoneOffset`, `KDuration` implement `Parcelable`.\n\n# Getting Started\n\n## First Step\n\nAdd the repository.\n```kotlin\n    repositories {\n        mavenCentral()\n    }\n```\n\nIn the KMM / KMP application build.gradle.kts, include the dependency in the `commonMain` source set.\n```kotlin\n    sourceSets {\n        val commonMain by getting {\n            dependencies {\n                api(\"io.github.sunny-chung:kdatetime-multiplatform:\u003cversion\u003e\")\n                // ...\n            }\n        }\n        // ...\n```\n\nAfter that, you can use KDateTime in any source set that depends on `commonMain` in Kotlin side.\n\n## To Use KDateTime in Swift / Objective-C\nAdd a transitive export to the `framework` DSL:\n```kotlin\n        framework {\n            baseName = \"shared\"\n            transitiveExport = true\n            export(\"io.github.sunny-chung:kdatetime-multiplatform:\u003cversion\u003e\")\n        }\n```\n\nIn native side, import your common framework to use.\n```swift\nimport shared\n```\n\n# Limitations\n- KDateTime does not deal with timezones. It deals with timezone offsets. There are no DST, calendar shifting, date skipping, leap seconds (but leap years are supported), etc..\n- So, only datetimes from year 1753 onwards are supported\n- Only timestamps between year 1753 and 3999 are supported\n- Minimum time unit is millisecond\n- English is default for locale-specific inputs and outputs (custom localized strings can be provided, check [documentation](https://sunny-chung.github.io/kdatetime-multiplatform/Features/Formatting%20and%20Parsing/))\n\n# For Developers\n\nThis section is only for developers who are interested in compiling or modifying this library.\n\n\u003c No content at this moment \u003e\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsunny-chung%2Fkdatetime-multiplatform","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fsunny-chung%2Fkdatetime-multiplatform","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsunny-chung%2Fkdatetime-multiplatform/lists"}