Skip to content

Commit

Permalink
More additions according to the reviews
Browse files Browse the repository at this point in the history
  • Loading branch information
dkhalanskyjb committed Apr 19, 2024
1 parent ac63d6c commit 01650af
Show file tree
Hide file tree
Showing 9 changed files with 67 additions and 3 deletions.
3 changes: 2 additions & 1 deletion core/common/src/Clock.kt
Original file line number Diff line number Diff line change
Expand Up @@ -46,9 +46,10 @@ public interface Clock {
* [TimeSource.Monotonic].
*
* For improved testability, one could avoid using [Clock.System] directly in the implementation,
* instead passing a [Clock] explicitly.
* instead passing a [Clock] explicitly. For example:
*
* @sample kotlinx.datetime.test.samples.ClockSamples.system
* @sample kotlinx.datetime.test.samples.ClockSamples.dependencyInjection
*/
public object System : Clock {
override fun now(): Instant = @Suppress("DEPRECATION_ERROR") Instant.now()
Expand Down
9 changes: 7 additions & 2 deletions core/common/src/DateTimePeriod.kt
Original file line number Diff line number Diff line change
Expand Up @@ -30,9 +30,11 @@ import kotlinx.serialization.Serializable
* All components can also be negative: for example, `DateTimePeriod(months = -5, days = 6, hours = -3)`.
* Whereas `months = 5` means "5 months after," `months = -5` means "5 months earlier."
*
* Since, semantically, a [DateTimePeriod] is a combination of [DateTimeUnit] values, in cases when the period is a
* fixed time interval (like "yearly" or "quarterly"), please consider using [DateTimeUnit] directly instead:
* A constant time interval that consists of a single non-zero component (like "yearly" or "quarterly") should be
* represented by a [DateTimeUnit] directly instead of a [DateTimePeriod]:
* for example, instead of `DateTimePeriod(months = 6)`, one could use `DateTimeUnit.MONTH * 6`.
* This provides a wider variety of operations: for example, finding how many such intervals fit between two instants
* or dates or adding a multiple of such intervals at once.
*
* ### Interaction with other entities
*
Expand Down Expand Up @@ -413,6 +415,9 @@ public fun String.toDateTimePeriod(): DateTimePeriod = DateTimePeriod.parse(this
* `DatePeriod` values are used in operations on [LocalDates][LocalDate] and are returned from operations
* on [LocalDates][LocalDate], but they also can be passed anywhere a [DateTimePeriod] is expected.
*
* On the JVM, there are `DatePeriod.toJavaPeriod()` and `java.time.Period.toKotlinDatePeriod()`
* extension functions.
*
* @sample kotlinx.datetime.test.samples.DateTimePeriodSamples.DatePeriodSamples.simpleParsingAndFormatting
*/
@Serializable(with = DatePeriodIso8601Serializer::class)
Expand Down
5 changes: 5 additions & 0 deletions core/common/src/Instant.kt
Original file line number Diff line number Diff line change
Expand Up @@ -131,6 +131,11 @@ import kotlin.time.*
* // 63 days until the concert, rounded down
* ```
*
* ### Platform specifics
*
* On the JVM, there are `Instant.toJavaInstant()` and `java.time.Instant.toKotlinInstant()` extension functions.
* On the Darwin platforms, there are `Instant.toNSDate()` and `NSDate.toKotlinInstant()` extension functions.
*
* ### Construction, serialization, and deserialization
*
* [fromEpochSeconds] can be used to construct an instant from the number of seconds since
Expand Down
9 changes: 9 additions & 0 deletions core/common/src/LocalDate.kt
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,15 @@ import kotlinx.serialization.Serializable
* - [LocalDate.periodUntil] (and [LocalDate.minus] that accepts a [LocalDate])
* can be used to find the [DatePeriod] between two dates.
*
* ### Platform specifics
*
* The range of supported years is platform-dependent, but at least is enough to represent dates of all instants between
* [Instant.DISTANT_PAST] and [Instant.DISTANT_FUTURE].
*
* On the JVM,
* there are `LocalDate.toJavaLocalDate()` and `java.time.LocalDate.toKotlinLocalDate()` extension functions.
* On the Darwin platforms, there is a `LocalDate.toNSDateComponents()` extension function.
*
* ### Construction, serialization, and deserialization
*
* [LocalDate] can be constructed directly from its components, using the constructor.
Expand Down
9 changes: 9 additions & 0 deletions core/common/src/LocalDateTime.kt
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,15 @@ import kotlinx.serialization.Serializable
* // 2021-03-29T02:16:20
* ```
*
* ### Platform specifics
*
* The range of supported years is platform-dependent, but at least is enough to represent dates of all instants between
* [Instant.DISTANT_PAST] and [Instant.DISTANT_FUTURE].
*
* On the JVM, there are `LocalDateTime.toJavaLocalDateTime()` and `java.time.LocalDateTime.toKotlinLocalDateTime()`
* extension functions.
* On the Darwin platforms, there is a `LocalDateTime.toNSDateComponents()` extension function.
*
* ### Construction, serialization, and deserialization
*
* **Pitfall**: since [LocalDateTime] is always constructed without specifying the time zone, it cannot validate
Expand Down
5 changes: 5 additions & 0 deletions core/common/src/LocalTime.kt
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,11 @@ import kotlinx.serialization.Serializable
* Because this pattern is extremely verbose and difficult to get right, it is recommended to work exclusively
* with [Instant] and only obtain a [LocalTime] when it is necessary to display the time to the user.
*
* ### Platform specifics
*
* On the JVM,
* there are `LocalTime.toJavaLocalTime()` and `java.time.LocalTime.toKotlinLocalTime()` extension functions.
*
* ### Construction, serialization, and deserialization
*
* [LocalTime] can be constructed directly from its components, using the constructor. See sample 1.
Expand Down
7 changes: 7 additions & 0 deletions core/common/src/TimeZone.kt
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,9 @@ import kotlinx.serialization.Serializable
* For interaction with `kotlinx-serialization`, [TimeZoneSerializer] is provided that serializes the time zone as its
* identifier.
*
* On the JVM, there are `TimeZone.toJavaZoneId()` and `java.time.ZoneId.toKotlinTimeZone()` extension functions.
* On the Darwin platforms, there are `TimeZone.toNSTimeZone()` and `NSTimeZone.toKotlinTimeZone()` extension functions.
*
* @sample kotlinx.datetime.test.samples.TimeZoneSamples.usage
*/
@Serializable(with = TimeZoneSerializer::class)
Expand Down Expand Up @@ -138,6 +141,10 @@ public expect open class TimeZone {
* Time zones that are [FixedOffsetTimeZone] at some point in time can become non-fixed in the future due to
* changes in legislation or other reasons.
*
* On the JVM, there are `FixedOffsetTimeZone.toJavaZoneOffset()` and
* `java.time.ZoneOffset.toKotlinFixedOffsetTimeZone()` extension functions.
* Note also the functions available for [TimeZone] in general.
*
* @sample kotlinx.datetime.test.samples.TimeZoneSamples.FixedOffsetTimeZoneSamples.casting
*/
@Serializable(with = FixedOffsetTimeZoneSerializer::class)
Expand Down
5 changes: 5 additions & 0 deletions core/common/src/UtcOffset.kt
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,11 @@ import kotlinx.serialization.Serializable
*
* See [TimeZone] for a type that represents a time zone.
*
* ### Platform specifics
*
* On the JVM, there are `UtcOffset.toJavaZoneOffset()` and `java.time.ZoneOffset.toKotlinUtcOffset()`
* extension functions.
*
* ### Construction, serialization, and deserialization
*
* To construct a [UtcOffset] value, use the [UtcOffset] constructor function.
Expand Down
18 changes: 18 additions & 0 deletions core/common/test/samples/ClockSamples.kt
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,24 @@ class ClockSamples {
currentLocalDateTime.toString() // show the current date and time, according to the OS
}

@Test
fun dependencyInjection() {
fun formatCurrentTime(clock: Clock, timeZone: TimeZone): String =
clock.now().toLocalDateTime(timeZone).toString()

// In the production code:
val currentTimeInProduction = formatCurrentTime(Clock.System, TimeZone.currentSystemDefault())
// Testing this value is tricky because it changes all the time.

// In the test code:
val testClock = object: Clock {
override fun now(): Instant = Instant.parse("2023-01-02T22:35:01Z")
}
// Then, one can write a completely deterministic test:
val currentTimeForTests = formatCurrentTime(testClock, TimeZone.of("Europe/Paris"))
check(currentTimeForTests == "2023-01-02T23:35:01")
}

@Test
fun todayIn() {
// Getting the current date in different time zones
Expand Down

0 comments on commit 01650af

Please sign in to comment.