Skip to content

Commit 01650af

Browse files
committed
More additions according to the reviews
1 parent ac63d6c commit 01650af

File tree

9 files changed

+67
-3
lines changed

9 files changed

+67
-3
lines changed

core/common/src/Clock.kt

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -46,9 +46,10 @@ public interface Clock {
4646
* [TimeSource.Monotonic].
4747
*
4848
* For improved testability, one could avoid using [Clock.System] directly in the implementation,
49-
* instead passing a [Clock] explicitly.
49+
* instead passing a [Clock] explicitly. For example:
5050
*
5151
* @sample kotlinx.datetime.test.samples.ClockSamples.system
52+
* @sample kotlinx.datetime.test.samples.ClockSamples.dependencyInjection
5253
*/
5354
public object System : Clock {
5455
override fun now(): Instant = @Suppress("DEPRECATION_ERROR") Instant.now()

core/common/src/DateTimePeriod.kt

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -30,9 +30,11 @@ import kotlinx.serialization.Serializable
3030
* All components can also be negative: for example, `DateTimePeriod(months = -5, days = 6, hours = -3)`.
3131
* Whereas `months = 5` means "5 months after," `months = -5` means "5 months earlier."
3232
*
33-
* Since, semantically, a [DateTimePeriod] is a combination of [DateTimeUnit] values, in cases when the period is a
34-
* fixed time interval (like "yearly" or "quarterly"), please consider using [DateTimeUnit] directly instead:
33+
* A constant time interval that consists of a single non-zero component (like "yearly" or "quarterly") should be
34+
* represented by a [DateTimeUnit] directly instead of a [DateTimePeriod]:
3535
* for example, instead of `DateTimePeriod(months = 6)`, one could use `DateTimeUnit.MONTH * 6`.
36+
* This provides a wider variety of operations: for example, finding how many such intervals fit between two instants
37+
* or dates or adding a multiple of such intervals at once.
3638
*
3739
* ### Interaction with other entities
3840
*
@@ -413,6 +415,9 @@ public fun String.toDateTimePeriod(): DateTimePeriod = DateTimePeriod.parse(this
413415
* `DatePeriod` values are used in operations on [LocalDates][LocalDate] and are returned from operations
414416
* on [LocalDates][LocalDate], but they also can be passed anywhere a [DateTimePeriod] is expected.
415417
*
418+
* On the JVM, there are `DatePeriod.toJavaPeriod()` and `java.time.Period.toKotlinDatePeriod()`
419+
* extension functions.
420+
*
416421
* @sample kotlinx.datetime.test.samples.DateTimePeriodSamples.DatePeriodSamples.simpleParsingAndFormatting
417422
*/
418423
@Serializable(with = DatePeriodIso8601Serializer::class)

core/common/src/Instant.kt

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -131,6 +131,11 @@ import kotlin.time.*
131131
* // 63 days until the concert, rounded down
132132
* ```
133133
*
134+
* ### Platform specifics
135+
*
136+
* On the JVM, there are `Instant.toJavaInstant()` and `java.time.Instant.toKotlinInstant()` extension functions.
137+
* On the Darwin platforms, there are `Instant.toNSDate()` and `NSDate.toKotlinInstant()` extension functions.
138+
*
134139
* ### Construction, serialization, and deserialization
135140
*
136141
* [fromEpochSeconds] can be used to construct an instant from the number of seconds since

core/common/src/LocalDate.kt

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,15 @@ import kotlinx.serialization.Serializable
2929
* - [LocalDate.periodUntil] (and [LocalDate.minus] that accepts a [LocalDate])
3030
* can be used to find the [DatePeriod] between two dates.
3131
*
32+
* ### Platform specifics
33+
*
34+
* The range of supported years is platform-dependent, but at least is enough to represent dates of all instants between
35+
* [Instant.DISTANT_PAST] and [Instant.DISTANT_FUTURE].
36+
*
37+
* On the JVM,
38+
* there are `LocalDate.toJavaLocalDate()` and `java.time.LocalDate.toKotlinLocalDate()` extension functions.
39+
* On the Darwin platforms, there is a `LocalDate.toNSDateComponents()` extension function.
40+
*
3241
* ### Construction, serialization, and deserialization
3342
*
3443
* [LocalDate] can be constructed directly from its components, using the constructor.

core/common/src/LocalDateTime.kt

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,15 @@ import kotlinx.serialization.Serializable
6060
* // 2021-03-29T02:16:20
6161
* ```
6262
*
63+
* ### Platform specifics
64+
*
65+
* The range of supported years is platform-dependent, but at least is enough to represent dates of all instants between
66+
* [Instant.DISTANT_PAST] and [Instant.DISTANT_FUTURE].
67+
*
68+
* On the JVM, there are `LocalDateTime.toJavaLocalDateTime()` and `java.time.LocalDateTime.toKotlinLocalDateTime()`
69+
* extension functions.
70+
* On the Darwin platforms, there is a `LocalDateTime.toNSDateComponents()` extension function.
71+
*
6372
* ### Construction, serialization, and deserialization
6473
*
6574
* **Pitfall**: since [LocalDateTime] is always constructed without specifying the time zone, it cannot validate

core/common/src/LocalTime.kt

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,11 @@ import kotlinx.serialization.Serializable
4545
* Because this pattern is extremely verbose and difficult to get right, it is recommended to work exclusively
4646
* with [Instant] and only obtain a [LocalTime] when it is necessary to display the time to the user.
4747
*
48+
* ### Platform specifics
49+
*
50+
* On the JVM,
51+
* there are `LocalTime.toJavaLocalTime()` and `java.time.LocalTime.toKotlinLocalTime()` extension functions.
52+
*
4853
* ### Construction, serialization, and deserialization
4954
*
5055
* [LocalTime] can be constructed directly from its components, using the constructor. See sample 1.

core/common/src/TimeZone.kt

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,9 @@ import kotlinx.serialization.Serializable
2525
* For interaction with `kotlinx-serialization`, [TimeZoneSerializer] is provided that serializes the time zone as its
2626
* identifier.
2727
*
28+
* On the JVM, there are `TimeZone.toJavaZoneId()` and `java.time.ZoneId.toKotlinTimeZone()` extension functions.
29+
* On the Darwin platforms, there are `TimeZone.toNSTimeZone()` and `NSTimeZone.toKotlinTimeZone()` extension functions.
30+
*
2831
* @sample kotlinx.datetime.test.samples.TimeZoneSamples.usage
2932
*/
3033
@Serializable(with = TimeZoneSerializer::class)
@@ -138,6 +141,10 @@ public expect open class TimeZone {
138141
* Time zones that are [FixedOffsetTimeZone] at some point in time can become non-fixed in the future due to
139142
* changes in legislation or other reasons.
140143
*
144+
* On the JVM, there are `FixedOffsetTimeZone.toJavaZoneOffset()` and
145+
* `java.time.ZoneOffset.toKotlinFixedOffsetTimeZone()` extension functions.
146+
* Note also the functions available for [TimeZone] in general.
147+
*
141148
* @sample kotlinx.datetime.test.samples.TimeZoneSamples.FixedOffsetTimeZoneSamples.casting
142149
*/
143150
@Serializable(with = FixedOffsetTimeZoneSerializer::class)

core/common/src/UtcOffset.kt

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,11 @@ import kotlinx.serialization.Serializable
2727
*
2828
* See [TimeZone] for a type that represents a time zone.
2929
*
30+
* ### Platform specifics
31+
*
32+
* On the JVM, there are `UtcOffset.toJavaZoneOffset()` and `java.time.ZoneOffset.toKotlinUtcOffset()`
33+
* extension functions.
34+
*
3035
* ### Construction, serialization, and deserialization
3136
*
3237
* To construct a [UtcOffset] value, use the [UtcOffset] constructor function.

core/common/test/samples/ClockSamples.kt

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,24 @@ class ClockSamples {
1818
currentLocalDateTime.toString() // show the current date and time, according to the OS
1919
}
2020

21+
@Test
22+
fun dependencyInjection() {
23+
fun formatCurrentTime(clock: Clock, timeZone: TimeZone): String =
24+
clock.now().toLocalDateTime(timeZone).toString()
25+
26+
// In the production code:
27+
val currentTimeInProduction = formatCurrentTime(Clock.System, TimeZone.currentSystemDefault())
28+
// Testing this value is tricky because it changes all the time.
29+
30+
// In the test code:
31+
val testClock = object: Clock {
32+
override fun now(): Instant = Instant.parse("2023-01-02T22:35:01Z")
33+
}
34+
// Then, one can write a completely deterministic test:
35+
val currentTimeForTests = formatCurrentTime(testClock, TimeZone.of("Europe/Paris"))
36+
check(currentTimeForTests == "2023-01-02T23:35:01")
37+
}
38+
2139
@Test
2240
fun todayIn() {
2341
// Getting the current date in different time zones

0 commit comments

Comments
 (0)