Skip to content

Feature Request: Add step functionality for date/time ranges #516

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
lonelymeko opened this issue Apr 9, 2025 · 1 comment
Closed

Feature Request: Add step functionality for date/time ranges #516

lonelymeko opened this issue Apr 9, 2025 · 1 comment

Comments

@lonelymeko
Copy link

Motivation:

Currently, iterating over a range of kotlinx-datetime types (LocalDate, LocalDateTime, Instant) with a specific step requires manual loop logic (e.g., using while and manually adding the step). This contrasts with standard Kotlin ranges (like IntRange, LongRange) which offer a convenient step() infix function for easy iteration.

Adding a similar step capability to kotlinx-datetime ranges would significantly improve usability for common tasks such as:

  • Generating data points at regular intervals (e.g., daily reports, hourly summaries).

  • Iterating through calendar views or schedules.

  • Processing time-series data with specific increments.

Proposed Solution (High-Level):

Introduce step infix extension functions that operate on ClosedRange where T is a kotlinx-datetime type. These functions would return an Iterable (or potentially a dedicated Progression type) allowing for iteration with a specified increment.
The appropriate step type would depend on the range type:

  • LocalDateRange: Step using DatePeriod.

  • InstantRange: Step using kotlin.time.Duration.

  • LocalDateTimeRange: Could potentially step using:

    DatePeriod (affecting the date part only).

    kotlin.time.Duration (affecting the whole date-time, but requires careful TimeZone handling).

    (Possibly DateTimePeriod as well, also requiring TimeZone handling)

Example Usage:

`import kotlinx.datetime.*
import kotlin.time.Duration.Companion.hours
import kotlin.time.Duration.Companion.days

val startDate = LocalDate(2024, 1, 1)
val endDate = LocalDate(2024, 1, 10)

// Iterate Wednesdays within the range (or similar period logic)
val weeklyPeriod = DatePeriod(days = 7) // Or calculate specific period
// for (date in startDate..endDate step weeklyPeriod) { ... } // Example goal

// Iterate every 2 days
for (date in startDate..endDate step DatePeriod(days = 2)) {
println(date) // 2024-01-01, 2024-01-03, ..., 2024-01-09
}

val startInstant = Clock.System.now()
val endInstant = startInstant + 1.days

// Iterate every 6 hours
for (instant in startInstant..endInstant step 6.hours) {
println(instant)
}

val startDateTime = LocalDateTime(2024, 3, 10, 1, 30) // DST change example
val endDateTime = startDateTime + 2.days

// Iterate by DatePeriod (time remains 01:30)
for (ldt in startDateTime..endDateTime step DatePeriod(days = 1)) {
println(ldt) // 2024-03-10 01:30, 2024-03-11 01:30, 2024-03-12 01:30
}

// Iterate by Duration (requires TimeZone context)
val zone = TimeZone.of("America/New_York")
// How should TimeZone be provided? This needs discussion.
// Example hypothetical API:
// for (ldt in startDateTime..endDateTime step (6.hours using zone)) {
// println(ldt) // e.g., 2024-03-10 01:30, 2024-03-10 07:30, ... (respecting DST)
// }`

Request for Feedback:

Would the kotlinx-datetime maintainers be interested in adding such step functionality to the library? If so, what would be the preferred API design, particularly regarding the TimeZone requirement for LocalDateTime steps involving time components (Duration, DateTimePeriod)?

I'd be potentially interested in contributing an implementation if a clear direction is established.

Thank you for considering this proposal.

@dkhalanskyjb
Copy link
Collaborator

Let's split this request into three parts.

  • LocalDateRange: we are about to merge Local date range #189, which adds this. Here's its discussion: Adding LocalDateRange #190, explaining why DatePeriod is not used for defining the step length.
  • InstantRange: if Duration is indeed used for stepping, then given that Instant is going to be moved into the standard library (Consider moving Instant and Clock to the standard library #382) and Duration is already there, it's completely outside the scope of kotlinx-datetime. Please use https://kotl.in/issue and describe your specific use case (business logic) there if you have one. During my research into how kotlinx-datetime is used, I haven't encountered many cases where it would be useful, though: usually, people stick to dates when iterating over time periods.
  • LocalDateTimeRange: we are not going to add that. Please see https://github.com/Kotlin/kotlinx-datetime?tab=readme-ov-file#date--time-arithmetic for an explanation of our approach to date + time arithmetic. As an example, val endDateTime = startDateTime + 2.days from your example will not compile in today's state of the library, and it shouldn't, as 2.days returns a Duration equal to 48 hours, not two calendar days, so adding it to a LocalDateTime is not a well-defined operation when no timezone is provided.

The only part of this proposal that is up for consideration is InstantRange, and that's a request for the standard library, so closing the issue.

@dkhalanskyjb dkhalanskyjb closed this as not planned Won't fix, can't repro, duplicate, stale Apr 9, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants