1 /**
2 * Copyright (C) 2022 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
5 * in compliance with the License. You may obtain a copy of the License at
6 *
7 * ```
8 * http://www.apache.org/licenses/LICENSE-2.0
9 * ```
10 *
11 * Unless required by applicable law or agreed to in writing, software distributed under the License
12 * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
13 * or implied. See the License for the specific language governing permissions and limitations under
14 * the License.
15 */
16 package com.android.healthconnect.controller.utils
17
18 import java.time.Duration
19 import java.time.Instant
20 import java.time.Instant.ofEpochMilli
21 import java.time.LocalDate
22 import java.time.LocalDateTime
23 import java.time.LocalTime
24 import java.time.ZoneId
25 import kotlin.random.Random
26
27 /**
28 * Returns an Instant with the specified year, month and day-of-month. The day must be valid for the
29 * year and month, otherwise an exception will be thrown.
30 *
31 * @param year the year to represent, from MIN_YEAR to MAX_YEAR
32 * @param month the month-of-year to represent, from 1 (January) to 12 (December)
33 * @param day the day-of-month to represent, from 1 to 31
34 */
getInstantnull35 fun getInstant(year: Int, month: Int, day: Int): Instant {
36 val date = LocalDate.of(year, month, day)
37 return date.atTime(LocalTime.MIDNIGHT).atZone(ZoneId.systemDefault()).toInstant()
38 }
39
Longnull40 fun Long.toInstant(): Instant {
41 return ofEpochMilli(this)
42 }
43
toLocalDatenull44 fun Instant.toLocalDate(): LocalDate {
45 return atZone(ZoneId.systemDefault()).toLocalDate()
46 }
47
Instantnull48 fun Instant.toLocalTime(): LocalTime {
49 return atZone(ZoneId.systemDefault()).toLocalTime()
50 }
51
Instantnull52 fun Instant.toLocalDateTime(): LocalDateTime {
53 return atZone(ZoneId.systemDefault()).toLocalDateTime()
54 }
55
Instantnull56 fun Instant.isOnSameDay(other: Instant): Boolean {
57 val localDate1 = this.toLocalDate()
58 val localDate2 = other.toLocalDate()
59 return localDate1 == localDate2
60 }
61
Instantnull62 fun Instant.isOnDayBefore(other: Instant): Boolean {
63 val localDate1 = this.toLocalDate()
64 val localDate2 = other.toLocalDate()
65 return localDate1 == localDate2.minusDays(1)
66 }
67
Instantnull68 fun Instant.isOnDayAfter(other: Instant): Boolean {
69 val localDate1 = this.toLocalDate()
70 val localDate2 = other.toLocalDate()
71 return localDate1 == localDate2.plusDays(1)
72 }
73
atStartOfDaynull74 fun Instant.atStartOfDay(): Instant {
75 return this.toLocalDate().atStartOfDay(ZoneId.systemDefault()).toInstant()
76 }
77
Instantnull78 fun Instant.isAtLeastOneDayAfter(other: Instant): Boolean {
79 val localDate1 = this.toLocalDate()
80 val localDate2 = other.toLocalDate()
81 return localDate1.isAfter(localDate2.plusDays(1)) || localDate1 == localDate2.plusDays(1)
82 }
83
toInstantAtStartOfDaynull84 fun LocalDate.toInstantAtStartOfDay(): Instant {
85 return this.atStartOfDay(ZoneId.systemDefault()).toInstant()
86 }
87
LocalDatenull88 fun LocalDate.randomInstant(): Instant {
89 val startOfDay = this.toInstantAtStartOfDay()
90
91 // Calculate the number of seconds in a day, accounting for daylight saving changes
92 val duration = Duration.between(startOfDay, this.plusDays(1).toInstantAtStartOfDay())
93 val secondsInDay = duration.seconds
94
95 // Generate a random offset in seconds within the day
96 val randomSecondOffset = Random.nextLong(secondsInDay)
97
98 // Return the calculated instant
99 return startOfDay.plusSeconds(randomSecondOffset)
100 }
101
LocalDateTimenull102 fun LocalDateTime.toInstant(): Instant {
103 return atZone(ZoneId.systemDefault()).toInstant()
104 }
105