{"id":18987034,"url":"https://github.com/whathecode/kotlinx.interval","last_synced_at":"2026-03-11T17:01:37.893Z","repository":{"id":39849684,"uuid":"491892386","full_name":"Whathecode/kotlinx.interval","owner":"Whathecode","description":"Kotlin multiplatform bounded open/closed generic intervals.","archived":false,"fork":false,"pushed_at":"2025-01-12T14:32:16.000Z","size":274,"stargazers_count":2,"open_issues_count":5,"forks_count":0,"subscribers_count":1,"default_branch":"develop","last_synced_at":"2025-03-29T13:21:51.532Z","etag":null,"topics":["hacktoberfest","kotlin","kotlin-multiplatform"],"latest_commit_sha":null,"homepage":"","language":"Kotlin","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/Whathecode.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":"2022-05-13T12:39:32.000Z","updated_at":"2025-01-12T14:32:20.000Z","dependencies_parsed_at":"2024-11-08T16:40:14.687Z","dependency_job_id":"3034d9cc-95bc-43f0-8248-bd2bd0fda7ec","html_url":"https://github.com/Whathecode/kotlinx.interval","commit_stats":{"total_commits":32,"total_committers":1,"mean_commits":32.0,"dds":0.0,"last_synced_commit":"ecccdc88b8746e5b5aaab9e7e3c7d423b76da9a6"},"previous_names":[],"tags_count":7,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Whathecode%2Fkotlinx.interval","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Whathecode%2Fkotlinx.interval/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Whathecode%2Fkotlinx.interval/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Whathecode%2Fkotlinx.interval/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/Whathecode","download_url":"https://codeload.github.com/Whathecode/kotlinx.interval/tar.gz/refs/heads/develop","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":249798934,"owners_count":21326930,"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":["hacktoberfest","kotlin","kotlin-multiplatform"],"created_at":"2024-11-08T16:38:10.401Z","updated_at":"2026-03-11T17:01:37.885Z","avatar_url":"https://github.com/Whathecode.png","language":"Kotlin","readme":"# Kotlin Multiplatform Bounded Open/Closed Generic Intervals\n\n[![Build](https://img.shields.io/github/actions/workflow/status/Whathecode/kotlinx.interval/publish-snapshots.yml\n)](https://github.com/Whathecode/kotlinx.interval/actions/workflows/publish-snapshots.yml)\n[![Snapshot](https://img.shields.io/maven-metadata/v?metadataUrl=https%3A%2F%2Fcentral.sonatype.com%2Frepository%2Fmaven-snapshots%2Fio%2Fgithub%2Fwhathecode%2Fkotlinx%2Finterval%2Fkotlinx-interval%2Fmaven-metadata.xml\n)](https://central.sonatype.com/repository/maven-snapshots/io/github/whathecode/kotlinx/interval/kotlinx-interval/maven-metadata.xml)\n[![Maven Central](https://img.shields.io/maven-central/v/io.github.whathecode.kotlinx.interval/kotlinx-interval\n)](https://central.sonatype.com/artifact/io.github.whathecode.kotlinx.interval/kotlinx-interval)\n\nRepresent closed, open, or half-open, bounded intervals in Kotlin and perform common operations on them.\n_Values_ covered by the interval can be of a different type than _distances_ between those values.\n\nFor example, `IntInterval` has `Int` values and `UInt` distances:\n\n```kotlin\nval interval: IntInterval = interval( 0, 10, isEndIncluded = false )\nval areIncluded = 0 in interval \u0026\u0026 5 in interval // true\nval areExcluded = 10 !in interval \u0026\u0026 15 !in interval // true\nval size: UInt = interval.size // 10\nval shifted = interval shr 10u // Shifted right by 10: [10, 20)\n```\n\nThis protects against overflows (e.g. if `size \u003e Int.MAX_VALUE`) but also offers better semantics.\nFor example, this library supports `Instant` values which are a `Duration` apart.\n\n```kotlin\nval now = Clock.System.now()\nval interval: InstantInterval = interval( now, now + 100.seconds )\nval areIncluded = now + 50.seconds in interval // true\nval size: Duration = interval.size // 100 seconds\nval shifted = interval shr 24.hours // 100 seconds 24 hours from now\n```\n\nIntervals support common math operations which allow concisely expressing common use cases.\n\n```kotlin\n// Two intervals of different types: a timeline visualized at some screen coordinates.\nval start2025 = LocalDateTime( 2025, 1, 1, 0, 0 ).toInstant( TimeZone.UTC )\nval end2025 = LocalDateTime( 2026, 1, 1, 0, 0 ).toInstant( TimeZone.UTC )\nval year2025: InstantInterval = interval( start2025, end2025 )\nval timelineUi: IntInterval = interval( 0, 800 ) // UI element 800 pixels wide\n\n// Find the selected time at a given UI coordinate using linear interpolation.\nval mouseX = 400\nval uiPercentage: Double = timelineUi.getPercentageFor( mouseX )\nval selectedTime: Instant = year2025.getValueAt( uiPercentage ) // July 2nd at noon.\n```\n\n\n## Interval Unions\n\nIntervals are a subset of _interval unions_, which represent a collection of intervals.\nThe result of operations on an interval can result in an interval union.\nSince operations are generally defined on the base interface, you can easily chain operations without caring about the concrete type.\n\n```kotlin\nval start = interval( 0, 100 ) // Interval: [0, 100]\nval areIncluded = 50 in start \u0026\u0026 100 in start // true\nval splitInTwo = start - interval( 25, 85 ) // Union: [[0, 25), (85, 100]]\nval shiftBackAndForth = splitInTwo shr 100u shl 100u // == splitInTwo\nval areExcluded = 50 !in splitInTwo \u0026\u0026 85 !in splitInTwo // true\nval unite = splitInTwo + interval( 10, 90 ) // Interval: [0, 100]\nval backToStart = start == unite // true\n```\n\nAn interval union contains any number of intervals.\n\n| Intervals in a union |             Description             | \n|:--------------------:|:-----------------------------------:|\n|          0           |            An empty set             |\n|          1           |             An interval             |\n|         \u003e 1          | Disjoint and non-adjacent intervals |\n\nIntervals in a union can be iterated over in order and don't intersect (are disjoint), and will always have _some_ values lying in between them (are non-adjacent).\nE.g., `[4, 5]` and `[6, 7]` are adjacent intervals in case they use integer types.\nTwo non-intersecting intervals with a shared endpoint are also adjacent, regardless of type, if one of the intervals includes the endpoint.\nE.g., `[4.0, 5.0)` and `[5.0, 7.0]` are adjacent.\nInstead, these are represented as a single interval: `[4, 7]` and `[4.0, 7.0]` respectively.\n\n## Operations\n\nIntervals and interval unions are immutable.\nOperations don't modify the instance the operation is executed on.\nInstead, new instances are returned if the operation results in a different set of values.\n\nThe following operations are available for any `IntervalUnion\u003cT, TSize\u003e`:\n\n|        Operation        |                                         Description                                          | \n|:-----------------------:|:--------------------------------------------------------------------------------------------:|\n|       `isEmpty()`       |                           Determines whether this is an empty set.                           |\n|      `getBounds()`      |                          Gets the upper and lower bound of the set.                          |\n|   `contains()` (`in`)   |                         Determines whether a value lies in the set.                          |\n|     `minus()` (`-`)     |                              Subtract an interval from the set.                              |\n|     `plus()` (`+`)      |                                 Add an interval to the set.                                  |\n| `shift()` (`shl`/`shr`) |                           Move the interval by a specified offset.                           |\n|     `intersects()`      |                Determines whether another interval intersects with this set.                 |\n|      `setEquals()`      |                     Determines whether a set represents the same values.                     |\n|      `iterator()`       |                      Iterate over all intervals in the union, in order.                      |\n|      `toString()`       | Output as a string using common interval notation, e.g., `[0, 10]` or `[[0, 10), (10, 20]]`. |\n\nThe following operations are specific to `Interval\u003cT, TSize\u003e`:\n\n|                   Operation                    |                                                Description                                                 | \n|:----------------------------------------------:|:----------------------------------------------------------------------------------------------------------:|\n|                 `start`, `end`                 |                     The values originally passed as the start and end of the interval.                     |\n|       `isStartIncluded`, `isEndIncluded`       |              Determines whether `start` and `end` respectively are included in the interval.               |\n|               `isClosedInterval`               |                  Determines whether both `start` and `end` are included in the interval.                   |\n|                `isOpenInterval`                |                 Determines whether both `start` and `end` are excluded from the interval.                  |\n|                  `isReversed`                  |                             Determines whether `start` is greater than `end`.                              |\n|           `lowerBound`, `upperBound`           |                       Corresponds to `start` and `end`, but swapped if `isReversed`.                       |\n| `isLowerBoundIncluded`, `isUpperBoundIncluded` |             Corresponds to `isStartIncluded` and `isEndIncluded`, but swapped if `isReversed`.             |\n|                     `size`                     |                             The absolute difference between `start` and `end`.                             |\n|                 `getValueAt()`                 |        Get the value at a given percentage inside (0.0–1.0) or outside (\u003c 0.0, \u003e 1.0) the interval.        |\n|              `getPercentageFor()`              |    Gets the percentage how far within (0.0-1.0) or outside (\u003c 0.0, \u003e 1.0) of the interval a value lies.    |\n|                `nonReversed()`                 |                             `reverse()` the interval in case it `isReversed`.                              |\n|                  `reverse()`                   |             Return an interval which swaps `start` with `end`, as well as boundary inclusions.             |\n|                `canonicalize()`                | Return the interval in canonical form. E.g., The canonical form of `[5, 1)` is `[2, 5]` for integer types. |\n\n## Interval Types\n\nThis library includes a generic base class `Interval\u003cT, TSize\u003e` which can be used to create intervals for any type.\nTo achieve this, it directs type operations to `IntervalTypeOperations` which the constructor takes as a parameter.\n\nThe following interval types are included in `io.github.whathecode.kotlinx.interval:kotlinx-interval` on Maven:\n\n|        Type        | Values (`T`) | Distances (`TSize`) |\n|:------------------:|:------------:|:-------------------:|\n|   `ByteInterval`   |    `Byte`    |       `UByte`       |\n|  `ShortInterval`   |   `Short`    |      `UShort`       |\n|   `IntInterval`    |    `Int`     |       `UInt`        |\n|   `LongInterval`   |    `Long`    |       `ULong`       |\n|  `FloatInterval`   |   `Float`    |      `Double`       |\n|  `DoubleInterval`  |   `Double`   |      `Double`       |\n|  `UByteInterval`   |   `UByte`    |       `UByte`       |\n|  `UShortInterval`  |   `UShort`   |      `UShort`       |\n|   `UIntInterval`   |    `UInt`    |       `UInt`        |\n|  `ULongInterval`   |   `ULong`    |       `ULong`       |\n|   `CharInterval`   |    `Char`    |      `UShort`       |\n| `InstantInterval`  |  `Instant`   |     `Duration`      |\n","funding_links":[],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fwhathecode%2Fkotlinx.interval","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fwhathecode%2Fkotlinx.interval","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fwhathecode%2Fkotlinx.interval/lists"}