diff --git a/screen/edit-transaction/src/main/java/com/ivy/transaction/EditTransactionScreen.kt b/screen/edit-transaction/src/main/java/com/ivy/transaction/EditTransactionScreen.kt index c400fae66d..b87a1f772e 100644 --- a/screen/edit-transaction/src/main/java/com/ivy/transaction/EditTransactionScreen.kt +++ b/screen/edit-transaction/src/main/java/com/ivy/transaction/EditTransactionScreen.kt @@ -35,6 +35,7 @@ import com.ivy.base.model.TransactionType import com.ivy.data.model.Category import com.ivy.data.model.Tag import com.ivy.data.model.TagId +import com.ivy.design.api.LocalTimeConverter import com.ivy.design.l0_system.Orange import com.ivy.design.l0_system.UI import com.ivy.design.l0_system.style @@ -84,9 +85,11 @@ import kotlinx.collections.immutable.ImmutableList import kotlinx.collections.immutable.ImmutableSet import kotlinx.collections.immutable.persistentListOf import kotlinx.collections.immutable.persistentSetOf +import java.time.Instant import java.time.LocalDate import java.time.LocalDateTime import java.time.LocalTime +import java.time.ZoneOffset import java.util.UUID import kotlin.math.roundToInt @@ -199,10 +202,10 @@ private fun BoxWithConstraintsScope.UI( titleSuggestions: ImmutableSet, description: String?, category: Category?, - dateTime: LocalDateTime?, + dateTime: Instant?, account: Account?, toAccount: Account?, - dueDate: LocalDateTime?, + dueDate: Instant?, amount: Double, customExchangeRateState: CustomExchangeRateState, @@ -357,10 +360,13 @@ private fun BoxWithConstraintsScope.UI( val ivyContext = ivyWalletCtx() + val timeConverter = LocalTimeConverter.current if (dueDate != null) { DueDate(dueDate = dueDate) { ivyContext.datePicker( - initialDate = dueDate.toLocalDate() + initialDate = with(timeConverter) { + dueDate.toLocalDate() + } ) { onDueDateChange(it.atTime(12, 0)) } @@ -380,14 +386,18 @@ private fun BoxWithConstraintsScope.UI( dueDateTime = dueDate, onEditDate = { ivyContext.datePicker( - initialDate = dateTime?.convertUTCtoLocal()?.toLocalDate() + initialDate = with(timeConverter) { + dateTime?.toLocalDate() + } ) { date -> onSetDate((date)) } }, onEditTime = { ivyContext.timePicker( - initialTime = dateTime?.toLocalTime() + initialTime = with(timeConverter) { + dateTime?.toLocalTime() + } ) { time -> onSetTime(time) } @@ -665,6 +675,7 @@ private fun shouldFocusAmount(amount: Double) = amount == 0.0 /** For Preview purpose **/ private val testDateTime = LocalDateTime.of(2023, 4, 27, 0, 35) + .toInstant(ZoneOffset.UTC) @ExperimentalFoundationApi @Preview diff --git a/screen/edit-transaction/src/main/java/com/ivy/transaction/EditTransactionViewModel.kt b/screen/edit-transaction/src/main/java/com/ivy/transaction/EditTransactionViewModel.kt index 06e5747de4..e4ff4ce69b 100644 --- a/screen/edit-transaction/src/main/java/com/ivy/transaction/EditTransactionViewModel.kt +++ b/screen/edit-transaction/src/main/java/com/ivy/transaction/EditTransactionViewModel.kt @@ -36,7 +36,6 @@ import com.ivy.legacy.domain.deprecated.logic.AccountCreator import com.ivy.legacy.utils.computationThread import com.ivy.legacy.utils.convertUTCToLocal import com.ivy.legacy.utils.dateNowLocal -import com.ivy.legacy.utils.getTrueDate import com.ivy.legacy.utils.ioThread import com.ivy.legacy.utils.timeUTC import com.ivy.legacy.utils.toLowerCaseLocal @@ -700,8 +699,8 @@ class EditTransactionViewModel @Inject constructor( description = description.value?.trim(), amount = amount, type = transactionType.value, - dueDate = with(timeConverter) { dueDate.value?.toUTC() }, - paidFor = with(timeConverter) { paidHistory.value?.toUTC() }, + dueDate = dueDate.value, + paidFor = paidHistory, dateTime = when { loadedTransaction().dateTime == null && dueDate.value == null -> { diff --git a/shared/base/src/main/java/com/ivy/base/time/TimeConverter.kt b/shared/base/src/main/java/com/ivy/base/time/TimeConverter.kt index 6fa1e93f9d..3d43582e30 100644 --- a/shared/base/src/main/java/com/ivy/base/time/TimeConverter.kt +++ b/shared/base/src/main/java/com/ivy/base/time/TimeConverter.kt @@ -3,10 +3,12 @@ package com.ivy.base.time import java.time.Instant import java.time.LocalDate import java.time.LocalDateTime +import java.time.LocalTime interface TimeConverter { fun Instant.toLocalDateTime(): LocalDateTime fun Instant.toLocalDate(): LocalDate + fun Instant.toLocalTime(): LocalTime fun LocalDateTime.toUTC(): Instant } \ No newline at end of file diff --git a/shared/base/src/main/java/com/ivy/base/time/impl/StandardTimeConverter.kt b/shared/base/src/main/java/com/ivy/base/time/impl/StandardTimeConverter.kt index 4cbb375a8e..e815b63ecb 100644 --- a/shared/base/src/main/java/com/ivy/base/time/impl/StandardTimeConverter.kt +++ b/shared/base/src/main/java/com/ivy/base/time/impl/StandardTimeConverter.kt @@ -8,6 +8,7 @@ import java.time.DateTimeException import java.time.Instant import java.time.LocalDate import java.time.LocalDateTime +import java.time.LocalTime import java.time.ZoneOffset import javax.inject.Inject @@ -43,4 +44,6 @@ class StandardTimeConverter @Inject constructor( val zoneId = timeZoneProvider.getZoneId() return this.atZone(zoneId).toInstant() } + + override fun Instant.toLocalTime(): LocalTime = toLocalDateTime().toLocalTime() } \ No newline at end of file diff --git a/temp/legacy-code/src/main/java/com/ivy/legacy/ui/component/edit/TransactionDateTime.kt b/temp/legacy-code/src/main/java/com/ivy/legacy/ui/component/edit/TransactionDateTime.kt index f1064330ab..a4980b5810 100644 --- a/temp/legacy-code/src/main/java/com/ivy/legacy/ui/component/edit/TransactionDateTime.kt +++ b/temp/legacy-code/src/main/java/com/ivy/legacy/ui/component/edit/TransactionDateTime.kt @@ -17,23 +17,23 @@ import androidx.compose.ui.res.stringResource import androidx.compose.ui.text.font.FontWeight import androidx.compose.ui.tooling.preview.Preview import androidx.compose.ui.unit.dp +import com.ivy.design.api.LocalTimeConverter +import com.ivy.design.api.LocalTimeFormatter +import com.ivy.design.api.LocalTimeProvider import com.ivy.design.l0_system.UI import com.ivy.design.l0_system.style import com.ivy.legacy.IvyWalletComponentPreview -import com.ivy.legacy.utils.formatNicely -import com.ivy.legacy.utils.formatTimeOnly -import com.ivy.legacy.utils.timeNowLocal -import com.ivy.legacy.utils.timeNowUTC import com.ivy.ui.R +import com.ivy.ui.time.TimeFormatter import com.ivy.wallet.ui.theme.components.IvyIcon -import java.time.LocalDateTime +import java.time.Instant @Suppress("MultipleEmitters") @Deprecated("Old design system. Use `:ivy-design` and Material3") @Composable fun TransactionDateTime( - dateTime: LocalDateTime?, - dueDateTime: LocalDateTime?, + dateTime: Instant?, + dueDateTime: Instant?, onEditDate: () -> Unit, onEditTime: () -> Unit, modifier: Modifier = Modifier @@ -67,10 +67,14 @@ fun TransactionDateTime( Spacer(Modifier.width(24.dp)) Spacer(Modifier.weight(1f)) + val localDateTime = with(LocalTimeConverter.current) { + (dateTime ?: LocalTimeProvider.current.utcNow()).toLocalDateTime() + } + val timeFormatter = LocalTimeFormatter.current Text( - text = (dateTime ?: timeNowUTC()).formatNicely( - noWeekDay = true - ), + text = with(timeFormatter) { + localDateTime.format(TimeFormatter.Style.DateOnly(includeWeekDay = false)) + }, style = UI.typo.nB2.style( color = UI.colors.pureInverse, fontWeight = FontWeight.ExtraBold @@ -79,8 +83,11 @@ fun TransactionDateTime( onEditDate() } ) + Text( - text = " " + (dateTime?.formatTimeOnly() ?: timeNowLocal().formatTimeOnly()), + text = " " + with(timeFormatter) { + localDateTime.toLocalTime().format() + }, style = UI.typo.nB2.style( color = UI.colors.pureInverse, fontWeight = FontWeight.ExtraBold @@ -99,7 +106,7 @@ fun TransactionDateTime( private fun Preview() { IvyWalletComponentPreview { TransactionDateTime( - dateTime = timeNowUTC(), + dateTime = LocalTimeProvider.current.utcNow(), dueDateTime = null, onEditDate = { }, diff --git a/temp/legacy-code/src/main/java/com/ivy/legacy/ui/component/edit/core/DueDate.kt b/temp/legacy-code/src/main/java/com/ivy/legacy/ui/component/edit/core/DueDate.kt index c9d95cd66d..631c8cefa9 100644 --- a/temp/legacy-code/src/main/java/com/ivy/legacy/ui/component/edit/core/DueDate.kt +++ b/temp/legacy-code/src/main/java/com/ivy/legacy/ui/component/edit/core/DueDate.kt @@ -16,19 +16,21 @@ import androidx.compose.ui.res.stringResource import androidx.compose.ui.text.font.FontWeight import androidx.compose.ui.tooling.preview.Preview import androidx.compose.ui.unit.dp +import com.ivy.design.api.LocalTimeFormatter +import com.ivy.design.api.LocalTimeProvider import com.ivy.design.l0_system.UI import com.ivy.design.l0_system.style import com.ivy.legacy.IvyWalletComponentPreview -import com.ivy.legacy.utils.formatDateOnly -import com.ivy.legacy.utils.timeNowUTC import com.ivy.ui.R +import com.ivy.ui.time.TimeFormatter import com.ivy.wallet.ui.theme.components.IvyIcon -import java.time.LocalDateTime +import java.time.Instant +import java.util.concurrent.TimeUnit @Deprecated("Old design system. Use `:ivy-design` and Material3") @Composable fun DueDate( - dueDate: LocalDateTime, + dueDate: Instant, onPickDueDate: () -> Unit, ) { DueDateCard( @@ -41,7 +43,7 @@ fun DueDate( @Composable private fun DueDateCard( - dueDate: LocalDateTime, + dueDate: Instant, onClick: () -> Unit, ) { Row( @@ -71,7 +73,9 @@ private fun DueDateCard( Spacer(Modifier.weight(1f)) Text( - text = dueDate.toLocalDate().formatDateOnly(), + text = with(LocalTimeFormatter.current) { + dueDate.formatLocal(TimeFormatter.Style.DateOnly(includeWeekDay = false)) + }, style = UI.typo.nB2.style( fontWeight = FontWeight.ExtraBold ) @@ -86,7 +90,8 @@ private fun DueDateCard( private fun Preview_OneTime() { IvyWalletComponentPreview { DueDate( - dueDate = timeNowUTC().plusDays(5), + dueDate = LocalTimeProvider.current.utcNow() + .plusSeconds(TimeUnit.DAYS.toSeconds(6)), ) { } } diff --git a/temp/legacy-code/src/main/java/com/ivy/legacy/utils/DateExt.kt b/temp/legacy-code/src/main/java/com/ivy/legacy/utils/DateExt.kt index d7f65340e3..0d4ca48160 100644 --- a/temp/legacy-code/src/main/java/com/ivy/legacy/utils/DateExt.kt +++ b/temp/legacy-code/src/main/java/com/ivy/legacy/utils/DateExt.kt @@ -42,6 +42,7 @@ fun LocalDateTime.toEpochSeconds() = this.toEpochSecond(ZoneOffset.UTC) fun LocalDateTime.millis() = this.toInstant(ZoneOffset.UTC).toEpochMilli() +@Deprecated("Use the TimeConverter interface via DI") fun LocalDateTime.formatNicely( noWeekDay: Boolean = false, zone: ZoneId = ZoneOffset.systemDefault() @@ -84,6 +85,7 @@ fun LocalDateTime.formatNicely( fun LocalDateTime.getISOFormattedDateTime(): String = this.formatLocal("yyyyMMdd-HHmm") +@Deprecated("Use the TimeConverter interface via DI") fun LocalDateTime.formatNicelyWithTime( noWeekDay: Boolean = true, zone: ZoneId = ZoneOffset.systemDefault() @@ -124,25 +126,25 @@ fun LocalDateTime.formatNicelyWithTime( } } +@Deprecated("Use the TimeConverter interface via DI") @Composable fun LocalDateTime.formatLocalTime(): String { val timeFormat = android.text.format.DateFormat.getTimeFormat(LocalContext.current) return timeFormat.format(this.millis()) } +@Deprecated("Use the TimeConverter interface via DI") fun LocalDate.formatDateOnly(): String = this.formatLocal("MMM. dd", ZoneOffset.systemDefault()) -fun LocalDateTime.formatTimeOnly(): String = this.format(DateTimeFormatter.ofPattern("HH:mm")) - +@Deprecated("Use the TimeConverter interface via DI") fun LocalDate.formatDateOnlyWithYear(): String = this.formatLocal("dd MMM, yyyy", ZoneOffset.systemDefault()) -fun LocalDate.formatDateWeekDay(): String = - this.formatLocal("EEE, dd MMM", ZoneOffset.systemDefault()) - +@Deprecated("Use the TimeConverter interface via DI") fun LocalDate.formatDateWeekDayLong(): String = this.formatLocal("EEEE, dd MMM", ZoneOffset.systemDefault()) +@Deprecated("Use the TimeConverter interface via DI") fun LocalDate.formatNicely( pattern: String = "EEE, dd MMM", patternNoWeekDay: String = "dd MMM",