Skip to content

Commit 272c4b2

Browse files
Extract Duration extension to a separate file
1 parent e48286a commit 272c4b2

File tree

4 files changed

+231
-269
lines changed

4 files changed

+231
-269
lines changed

WooCommerce/src/main/kotlin/com/woocommerce/android/ui/bookings/BookingMapper.kt

Lines changed: 4 additions & 73 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,8 @@ import com.woocommerce.android.ui.bookings.compose.BookingSummaryModel
1515
import com.woocommerce.android.ui.bookings.details.CancelStatus
1616
import com.woocommerce.android.ui.bookings.list.BookingListItem
1717
import com.woocommerce.android.util.CurrencyFormatter
18+
import com.woocommerce.android.util.normalizeDuration
19+
import com.woocommerce.android.util.toHumanReadableFormat
1820
import com.woocommerce.android.viewmodel.ResourceProvider
1921
import kotlinx.coroutines.Dispatchers
2022
import kotlinx.coroutines.withContext
@@ -65,8 +67,8 @@ class BookingMapper @Inject constructor(
6567
cancelStatus: CancelStatus,
6668
): BookingAppointmentDetailsModel {
6769
val duration = Duration.between(start, end)
68-
.normalizeBookingDuration()
69-
.toHumanReadableFormat()
70+
.normalizeDuration()
71+
.toHumanReadableFormat(resourceProvider)
7072
return BookingAppointmentDetailsModel(
7173
date = detailsDateFormatter.format(start),
7274
time = "${timeRangeFormatter.format(start)} - ${timeRangeFormatter.format(end)}",
@@ -135,77 +137,6 @@ class BookingMapper @Inject constructor(
135137
)
136138
}
137139

138-
/**
139-
* Normalize booking duration by adjusting for precision issues.
140-
*
141-
* This function handles cases where a booking duration is very close to
142-
* common time boundaries (days/hours) but falls short due to precision issues.
143-
* It rounds up durations that are within one minute of these boundaries.
144-
*/
145-
private fun Duration.normalizeBookingDuration(): Duration {
146-
val dayInSeconds = Duration.ofDays(1).seconds
147-
val hourInSeconds = Duration.ofHours(1).seconds
148-
val minuteInSeconds = Duration.ofMinutes(1).seconds
149-
150-
var durationInSeconds = this.seconds
151-
val boundaries = listOf(dayInSeconds, hourInSeconds)
152-
for (boundary in boundaries) {
153-
val remainder = durationInSeconds % boundary
154-
val difference = if (remainder == 0L) 0L else boundary - remainder
155-
if (difference > 0 && difference <= minuteInSeconds) {
156-
durationInSeconds += difference
157-
}
158-
}
159-
return Duration.ofSeconds(durationInSeconds)
160-
}
161-
162-
@Suppress("LongMethod")
163-
private fun Duration.toHumanReadableFormat(): String {
164-
if (this < Duration.ofMinutes(1)) {
165-
return resourceProvider.getQuantityString(
166-
quantity = seconds.toInt(),
167-
default = R.string.booking_duration_seconds,
168-
one = R.string.booking_duration_second
169-
)
170-
}
171-
172-
val days = toDays()
173-
val hours = minusDays(days).toHours()
174-
val minutes = minusDays(days).minusHours(hours).toMinutes()
175-
176-
return buildString {
177-
if (days > 0) {
178-
append(
179-
resourceProvider.getQuantityString(
180-
quantity = days.toInt(),
181-
default = R.string.booking_duration_days,
182-
one = R.string.booking_duration_day
183-
)
184-
)
185-
}
186-
if (hours > 0) {
187-
append(" ")
188-
append(
189-
resourceProvider.getQuantityString(
190-
quantity = hours.toInt(),
191-
default = R.string.booking_duration_hours,
192-
one = R.string.booking_duration_hour
193-
)
194-
)
195-
}
196-
if (minutes > 0) {
197-
append(" ")
198-
append(
199-
resourceProvider.getQuantityString(
200-
quantity = minutes.toInt(),
201-
default = R.string.booking_duration_minutes,
202-
one = R.string.booking_duration_minute
203-
)
204-
)
205-
}
206-
}.trim()
207-
}
208-
209140
private suspend fun BookingCustomerInfo.address(): Address? {
210141
val countryCode = billingCountry ?: return null
211142
val (country, state) = withContext(Dispatchers.IO) {
Lines changed: 76 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,76 @@
1+
package com.woocommerce.android.util
2+
3+
import com.woocommerce.android.R
4+
import com.woocommerce.android.viewmodel.ResourceProvider
5+
import java.time.Duration
6+
7+
/**
8+
* Normalize duration by adjusting for precision issues.
9+
*
10+
* This function handles cases where a booking duration is very close to
11+
* common time boundaries (days/hours) but falls short due to precision issues.
12+
* It rounds up durations that are within one minute of these boundaries.
13+
*/
14+
fun Duration.normalizeDuration(): Duration {
15+
val dayInSeconds = Duration.ofDays(1).seconds
16+
val hourInSeconds = Duration.ofHours(1).seconds
17+
val minuteInSeconds = Duration.ofMinutes(1).seconds
18+
19+
var durationInSeconds = this.seconds
20+
val boundaries = listOf(dayInSeconds, hourInSeconds)
21+
for (boundary in boundaries) {
22+
val remainder = durationInSeconds % boundary
23+
val difference = if (remainder == 0L) 0L else boundary - remainder
24+
if (difference > 0 && difference <= minuteInSeconds) {
25+
durationInSeconds += difference
26+
}
27+
}
28+
return Duration.ofSeconds(durationInSeconds)
29+
}
30+
31+
@Suppress("LongMethod")
32+
fun Duration.toHumanReadableFormat(resourceProvider: ResourceProvider): String {
33+
if (this < Duration.ofMinutes(1)) {
34+
return resourceProvider.getQuantityString(
35+
quantity = seconds.toInt(),
36+
default = R.string.booking_duration_seconds,
37+
one = R.string.booking_duration_second
38+
)
39+
}
40+
41+
val days = toDays()
42+
val hours = minusDays(days).toHours()
43+
val minutes = minusDays(days).minusHours(hours).toMinutes()
44+
45+
return buildString {
46+
if (days > 0) {
47+
append(
48+
resourceProvider.getQuantityString(
49+
quantity = days.toInt(),
50+
default = R.string.booking_duration_days,
51+
one = R.string.booking_duration_day
52+
)
53+
)
54+
}
55+
if (hours > 0) {
56+
append(" ")
57+
append(
58+
resourceProvider.getQuantityString(
59+
quantity = hours.toInt(),
60+
default = R.string.booking_duration_hours,
61+
one = R.string.booking_duration_hour
62+
)
63+
)
64+
}
65+
if (minutes > 0) {
66+
append(" ")
67+
append(
68+
resourceProvider.getQuantityString(
69+
quantity = minutes.toInt(),
70+
default = R.string.booking_duration_minutes,
71+
one = R.string.booking_duration_minute
72+
)
73+
)
74+
}
75+
}.trim()
76+
}

0 commit comments

Comments
 (0)