refactor: OffsetDateTime.now()를 KST 기준으로 수정

This commit is contained in:
이상진 2025-10-05 20:55:31 +09:00
parent 48ee01eb9e
commit 93cff516a1
9 changed files with 39 additions and 27 deletions

View File

@ -15,6 +15,7 @@ object KoreaTime {
object KoreaDateTime { object KoreaDateTime {
fun now(): LocalDateTime = LocalDateTime.now(KST_CLOCK) fun now(): LocalDateTime = LocalDateTime.now(KST_CLOCK)
fun nowWithOffset(): OffsetDateTime = OffsetDateTime.now(KST_CLOCK)
} }
fun Instant.toKoreaDateTime(): LocalDateTime = this.atZone(KST_CLOCK.zone).toLocalDateTime() fun Instant.toKoreaDateTime(): LocalDateTime = this.atZone(KST_CLOCK.zone).toLocalDateTime()

View File

@ -3,12 +3,9 @@ package com.sangdol.common.utils
import io.kotest.assertions.assertSoftly import io.kotest.assertions.assertSoftly
import io.kotest.core.spec.style.FunSpec import io.kotest.core.spec.style.FunSpec
import io.kotest.matchers.shouldBe import io.kotest.matchers.shouldBe
import java.time.Instant import java.time.*
import java.time.LocalDateTime
import java.time.LocalTime
import java.time.ZoneId
class KoreaDateTimeExtensions : FunSpec({ class KoreaDateTimeExtensionsTest : FunSpec({
test("한국 시간 기준으로 현재 시간을 가져오며, 초 단위는 제외한다.") { test("한국 시간 기준으로 현재 시간을 가져오며, 초 단위는 제외한다.") {
assertSoftly(KoreaTime.now()) { assertSoftly(KoreaTime.now()) {
@ -21,7 +18,7 @@ class KoreaDateTimeExtensions : FunSpec({
} }
} }
test("한국 시간 기준으로 현재 날짜 + 시간을 가져온다.") { test("한국 시간 기준으로 현재 날짜 + 시간을 LocalDateTime 타입으로 가져온다.") {
assertSoftly(KoreaDateTime.now()) { assertSoftly(KoreaDateTime.now()) {
val utcNow = LocalDateTime.now(ZoneId.of("UTC")) val utcNow = LocalDateTime.now(ZoneId.of("UTC"))
@ -29,7 +26,15 @@ class KoreaDateTimeExtensions : FunSpec({
} }
} }
test("UTC 시간을 한국 시간으로 변환한다.") { test("한국 시간 기준으로 현재 날짜 + 시간을 OffsetDateTime 타입으로 가져온다.") {
assertSoftly(KoreaDateTime.nowWithOffset()) {
val utcNow = OffsetDateTime.now(ZoneId.of("UTC"))
this.toLocalDateTime().withSecond(0).withNano(0) shouldBe utcNow.toLocalDateTime().plusHours(9).withSecond(0).withNano(0)
}
}
test("UTC 시간을 LocalDateTime 타입의 한국 시간으로 변환한다.") {
val now = Instant.now() val now = Instant.now()
val kstConverted = now.toKoreaDateTime() val kstConverted = now.toKoreaDateTime()
val utc = now.atZone(ZoneId.of("UTC")).toLocalDateTime() val utc = now.atZone(ZoneId.of("UTC")).toLocalDateTime()

View File

@ -2,6 +2,7 @@ package com.sangdol.data
import com.sangdol.common.persistence.IDGenerator import com.sangdol.common.persistence.IDGenerator
import com.sangdol.common.persistence.TransactionExecutionUtil import com.sangdol.common.persistence.TransactionExecutionUtil
import com.sangdol.common.utils.KoreaDateTime
import com.sangdol.roomescape.admin.infrastructure.persistence.AdminEntity import com.sangdol.roomescape.admin.infrastructure.persistence.AdminEntity
import com.sangdol.roomescape.admin.infrastructure.persistence.AdminPermissionLevel import com.sangdol.roomescape.admin.infrastructure.persistence.AdminPermissionLevel
import com.sangdol.roomescape.admin.infrastructure.persistence.AdminType import com.sangdol.roomescape.admin.infrastructure.persistence.AdminType
@ -629,8 +630,8 @@ data class PaymentWithMethods(
class PaymentDataInitializer : AbstractDataInitializer() { class PaymentDataInitializer : AbstractDataInitializer() {
companion object { companion object {
val requestedAtCache: Timestamp = Timestamp.valueOf(OffsetDateTime.now().toLocalDateTime()) val requestedAtCache: Timestamp = Timestamp.valueOf(KoreaDateTime.nowWithOffset().toLocalDateTime())
val approvedAtCache: Timestamp = Timestamp.valueOf(OffsetDateTime.now().plusSeconds(5).toLocalDateTime()) val approvedAtCache: Timestamp = Timestamp.valueOf(KoreaDateTime.nowWithOffset().plusSeconds(5).toLocalDateTime())
val supportedPaymentMethods = listOf(PaymentMethod.TRANSFER, PaymentMethod.EASY_PAY, PaymentMethod.CARD) val supportedPaymentMethods = listOf(PaymentMethod.TRANSFER, PaymentMethod.EASY_PAY, PaymentMethod.CARD)
val supportedCardType = listOf(CardType.CREDIT, CardType.CHECK) val supportedCardType = listOf(CardType.CREDIT, CardType.CHECK)

View File

@ -1,5 +1,6 @@
package com.sangdol.roomescape.payment package com.sangdol.roomescape.payment
import com.sangdol.common.utils.KoreaDateTime
import java.time.OffsetDateTime import java.time.OffsetDateTime
object SampleTosspayConstant { object SampleTosspayConstant {
@ -39,8 +40,8 @@ object SampleTosspayConstant {
"orderName": "Sonya Aguirre 예약 결제", "orderName": "Sonya Aguirre 예약 결제",
"taxExemptionAmount": 0, "taxExemptionAmount": 0,
"status": "DONE", "status": "DONE",
"requestedAt": "${OffsetDateTime.now()}", "requestedAt": "${KoreaDateTime.nowWithOffset()}",
"approvedAt": "${OffsetDateTime.now().plusSeconds(5)}", "approvedAt": "${KoreaDateTime.nowWithOffset().plusSeconds(5)}",
"useEscrow": false, "useEscrow": false,
"cultureExpense": false, "cultureExpense": false,
"card": { "card": {
@ -102,8 +103,8 @@ object SampleTosspayConstant {
"orderName": "Sonya Aguirre 예약 결제", "orderName": "Sonya Aguirre 예약 결제",
"taxExemptionAmount": 0, "taxExemptionAmount": 0,
"status": "CANCELED", "status": "CANCELED",
"requestedAt": "${OffsetDateTime.now()}", "requestedAt": "${KoreaDateTime.nowWithOffset()}",
"approvedAt": "${OffsetDateTime.now().plusSeconds(5)}", "approvedAt": "${KoreaDateTime.nowWithOffset().plusSeconds(5)}",
"useEscrow": false, "useEscrow": false,
"cultureExpense": false, "cultureExpense": false,
"card": { "card": {
@ -132,7 +133,7 @@ object SampleTosspayConstant {
"transactionKey": "txrd_a01k4mtgh26vgrn1evbdckyqmdr", "transactionKey": "txrd_a01k4mtgh26vgrn1evbdckyqmdr",
"cancelReason": "$CANCEL_REASON", "cancelReason": "$CANCEL_REASON",
"taxExemptionAmount": 0, "taxExemptionAmount": 0,
"canceledAt": "${OffsetDateTime.now().plusMinutes(1)}", "canceledAt": "${KoreaDateTime.nowWithOffset().plusMinutes(1)}",
"cardDiscountAmount": 0, "cardDiscountAmount": 0,
"transferDiscountAmount": 0, "transferDiscountAmount": 0,
"easyPayDiscountAmount": 0, "easyPayDiscountAmount": 0,
@ -181,8 +182,8 @@ object SampleTosspayConstant {
"orderName": "Sonya Aguirre 예약 결제", "orderName": "Sonya Aguirre 예약 결제",
"taxExemptionAmount": 0, "taxExemptionAmount": 0,
"status": "DONE", "status": "DONE",
"requestedAt": "${OffsetDateTime.now()}", "requestedAt": "${KoreaDateTime.nowWithOffset()}",
"approvedAt": "${OffsetDateTime.now().plusSeconds(5)}", "approvedAt": "${KoreaDateTime.nowWithOffset().plusSeconds(5)}",
"useEscrow": false, "useEscrow": false,
"cultureExpense": false, "cultureExpense": false,
"card": null, "card": null,
@ -230,8 +231,8 @@ object SampleTosspayConstant {
"orderName": "Sonya Aguirre 예약 결제", "orderName": "Sonya Aguirre 예약 결제",
"taxExemptionAmount": 0, "taxExemptionAmount": 0,
"status": "DONE", "status": "DONE",
"requestedAt": "${OffsetDateTime.now()}", "requestedAt": "${KoreaDateTime.nowWithOffset()}",
"approvedAt": "${OffsetDateTime.now().plusSeconds(5)}", "approvedAt": "${KoreaDateTime.nowWithOffset().plusSeconds(5)}",
"useEscrow": false, "useEscrow": false,
"cultureExpense": false, "cultureExpense": false,
"card": null, "card": null,
@ -250,7 +251,7 @@ object SampleTosspayConstant {
"transactionKey": "txrd_a01k4mtgh26vgrn1evbdckyqmdr", "transactionKey": "txrd_a01k4mtgh26vgrn1evbdckyqmdr",
"cancelReason": "$CANCEL_REASON", "cancelReason": "$CANCEL_REASON",
"taxExemptionAmount": 0, "taxExemptionAmount": 0,
"canceledAt": "${OffsetDateTime.now().plusMinutes(1)}", "canceledAt": "${KoreaDateTime.nowWithOffset().plusMinutes(1)}",
"cardDiscountAmount": 0, "cardDiscountAmount": 0,
"transferDiscountAmount": 0, "transferDiscountAmount": 0,
"easyPayDiscountAmount": 0, "easyPayDiscountAmount": 0,

View File

@ -2,6 +2,7 @@ package com.sangdol.roomescape.supports
import com.github.f4b6a3.tsid.TsidFactory import com.github.f4b6a3.tsid.TsidFactory
import com.sangdol.common.persistence.TsidIDGenerator import com.sangdol.common.persistence.TsidIDGenerator
import com.sangdol.common.utils.KoreaDateTime
import com.sangdol.roomescape.admin.infrastructure.persistence.AdminEntity import com.sangdol.roomescape.admin.infrastructure.persistence.AdminEntity
import com.sangdol.roomescape.admin.infrastructure.persistence.AdminPermissionLevel import com.sangdol.roomescape.admin.infrastructure.persistence.AdminPermissionLevel
import com.sangdol.roomescape.admin.infrastructure.persistence.AdminType import com.sangdol.roomescape.admin.infrastructure.persistence.AdminType
@ -297,8 +298,8 @@ object PaymentFixture {
card = cardDetail, card = cardDetail,
easyPay = easyPayDetail, easyPay = easyPayDetail,
transfer = transferDetail, transfer = transferDetail,
requestedAt = OffsetDateTime.now(), requestedAt = KoreaDateTime.nowWithOffset(),
approvedAt = OffsetDateTime.now().plusSeconds(5) approvedAt = KoreaDateTime.nowWithOffset().plusSeconds(5)
) )
fun cancelResponse( fun cancelResponse(
@ -314,7 +315,7 @@ object PaymentFixture {
cardDiscountAmount = cardDiscountAmount, cardDiscountAmount = cardDiscountAmount,
transferDiscountAmount = transferDiscountAmount, transferDiscountAmount = transferDiscountAmount,
easyPayDiscountAmount = easypayDiscountAmount, easyPayDiscountAmount = easypayDiscountAmount,
canceledAt = OffsetDateTime.now().plusSeconds(5), canceledAt = KoreaDateTime.nowWithOffset().plusSeconds(5),
cancelReason = cancelReason cancelReason = cancelReason
), ),
) )

View File

@ -1,5 +1,6 @@
package com.sangdol.tosspaymock.business.domain package com.sangdol.tosspaymock.business.domain
import com.sangdol.common.utils.KoreaDateTime
import com.sangdol.tosspaymock.business.domain.cancel.Cancellation import com.sangdol.tosspaymock.business.domain.cancel.Cancellation
import com.sangdol.tosspaymock.business.domain.card.Card import com.sangdol.tosspaymock.business.domain.card.Card
import com.sangdol.tosspaymock.business.domain.easypay.Easypay import com.sangdol.tosspaymock.business.domain.easypay.Easypay
@ -128,7 +129,7 @@ class Payment(
return create( return create(
paymentKey = paymentKey, paymentKey = paymentKey,
orderId = "orderId", orderId = "orderId",
requestedAt = OffsetDateTime.now(), requestedAt = KoreaDateTime.nowWithOffset(),
amount = cancellation.cancelAmount, amount = cancellation.cancelAmount,
card = null, card = null,
easyPay = null, easyPay = null,
@ -165,7 +166,7 @@ class Payment(
orderId = orderId, orderId = orderId,
orderName = "테스트 결제", orderName = "테스트 결제",
requestedAt = requestedAt, requestedAt = requestedAt,
approvedAt = OffsetDateTime.now(), approvedAt = KoreaDateTime.nowWithOffset(),
card = card, card = card,
easyPay = easyPay, easyPay = easyPay,
transfer = bankTransfer, transfer = bankTransfer,

View File

@ -1,5 +1,6 @@
package com.sangdol.tosspaymock.business.domain.cancel package com.sangdol.tosspaymock.business.domain.cancel
import com.sangdol.common.utils.KoreaDateTime
import com.sangdol.tosspaymock.business.domain.RandomPaymentValueGenerator import com.sangdol.tosspaymock.business.domain.RandomPaymentValueGenerator
import com.sangdol.tosspaymock.web.dto.CancelResponse import com.sangdol.tosspaymock.web.dto.CancelResponse
import java.time.OffsetDateTime import java.time.OffsetDateTime
@ -29,7 +30,7 @@ class Cancellation(
) = Cancellation( ) = Cancellation(
transactionKey = RandomPaymentValueGenerator.transactionKey(), transactionKey = RandomPaymentValueGenerator.transactionKey(),
cancelReason = cancelReason, cancelReason = cancelReason,
canceledAt = OffsetDateTime.now(), canceledAt = KoreaDateTime.nowWithOffset(),
cardDiscountAmount = cardDiscountAmount, cardDiscountAmount = cardDiscountAmount,
transferDiscountAmount = transferDiscountAmount, transferDiscountAmount = transferDiscountAmount,
easyPayDiscountAmount = easyPayDiscountAmount, easyPayDiscountAmount = easyPayDiscountAmount,

View File

@ -1,12 +1,13 @@
package com.sangdol.tosspaymock.web.dto package com.sangdol.tosspaymock.web.dto
import com.sangdol.common.utils.KoreaDateTime
import java.time.OffsetDateTime import java.time.OffsetDateTime
data class PaymentConfirmRequest( data class PaymentConfirmRequest(
val paymentKey: String, val paymentKey: String,
val orderId: String, val orderId: String,
val amount: Int, val amount: Int,
val requestedAt: OffsetDateTime = OffsetDateTime.now() val requestedAt: OffsetDateTime = KoreaDateTime.nowWithOffset()
) )
data class PaymentCancelRequest( data class PaymentCancelRequest(