Removed also most other DateTime extension methods

This commit is contained in:
dankito 2024-08-19 10:53:59 +02:00
parent e9cad57e71
commit 2e13a153bd
13 changed files with 31 additions and 137 deletions

View File

@ -4,7 +4,7 @@ import kotlinx.datetime.LocalDate
import kotlinx.serialization.Serializable import kotlinx.serialization.Serializable
import net.dankito.banking.fints.model.Amount import net.dankito.banking.fints.model.Amount
import net.dankito.banking.fints.model.Money import net.dankito.banking.fints.model.Money
import net.dankito.utils.multiplatform.extensions.atUnixEpochStart import net.dankito.utils.multiplatform.extensions.UnixEpochStart
@Serializable @Serializable
@ -47,7 +47,7 @@ open class AccountTransaction(
) { ) {
// for object deserializers // for object deserializers
internal constructor() : this(Money(Amount.Zero, ""), "", LocalDate.atUnixEpochStart, null, null, null, null, LocalDate.atUnixEpochStart) internal constructor() : this(Money(Amount.Zero, ""), "", UnixEpochStart, null, null, null, null, UnixEpochStart)
constructor(amount: Money, unparsedReference: String, bookingDate: LocalDate, otherPartyName: String?, otherPartyBankCode: String?, otherPartyAccountId: String?, bookingText: String?, valueDate: LocalDate) constructor(amount: Money, unparsedReference: String, bookingDate: LocalDate, otherPartyName: String?, otherPartyBankCode: String?, otherPartyAccountId: String?, bookingText: String?, valueDate: LocalDate)
: this(amount, unparsedReference, bookingDate, otherPartyName, otherPartyBankCode, otherPartyAccountId, bookingText, valueDate, : this(amount, unparsedReference, bookingDate, otherPartyName, otherPartyBankCode, otherPartyAccountId, bookingText, valueDate,

View File

@ -1,16 +1,14 @@
package net.dankito.banking.fints package net.dankito.banking.fints
import kotlinx.datetime.LocalDate
import net.dankito.banking.client.model.parameter.FinTsClientParameter import net.dankito.banking.client.model.parameter.FinTsClientParameter
import net.dankito.banking.fints.callback.FinTsClientCallback
import net.dankito.banking.fints.model.*
import net.dankito.banking.client.model.parameter.GetAccountDataParameter import net.dankito.banking.client.model.parameter.GetAccountDataParameter
import net.dankito.banking.client.model.parameter.RetrieveTransactions
import net.dankito.banking.client.model.parameter.TransferMoneyParameter import net.dankito.banking.client.model.parameter.TransferMoneyParameter
import net.dankito.banking.client.model.response.ErrorCode import net.dankito.banking.client.model.response.ErrorCode
import net.dankito.banking.client.model.response.GetAccountDataResponse import net.dankito.banking.client.model.response.GetAccountDataResponse
import net.dankito.banking.client.model.response.TransferMoneyResponse import net.dankito.banking.client.model.response.TransferMoneyResponse
import net.dankito.banking.fints.callback.FinTsClientCallback
import net.dankito.banking.fints.mapper.FinTsModelMapper import net.dankito.banking.fints.mapper.FinTsModelMapper
import net.dankito.banking.fints.model.*
import net.dankito.banking.fints.response.client.FinTsClientResponse import net.dankito.banking.fints.response.client.FinTsClientResponse
import net.dankito.banking.fints.response.client.GetAccountInfoResponse import net.dankito.banking.fints.response.client.GetAccountInfoResponse
import net.dankito.banking.fints.response.client.GetAccountTransactionsResponse import net.dankito.banking.fints.response.client.GetAccountTransactionsResponse
@ -18,8 +16,6 @@ import net.dankito.banking.fints.response.segments.AccountType
import net.dankito.banking.fints.util.BicFinder import net.dankito.banking.fints.util.BicFinder
import net.dankito.banking.fints.util.FinTsServerAddressFinder import net.dankito.banking.fints.util.FinTsServerAddressFinder
import net.dankito.banking.fints.webclient.IWebClient import net.dankito.banking.fints.webclient.IWebClient
import net.dankito.utils.multiplatform.extensions.minusDays
import net.dankito.utils.multiplatform.extensions.todayAtEuropeBerlin
import kotlin.jvm.JvmOverloads import kotlin.jvm.JvmOverloads

View File

@ -18,7 +18,6 @@ import net.dankito.banking.fints.response.segments.*
import net.dankito.banking.fints.tan.FlickerCodeDecoder import net.dankito.banking.fints.tan.FlickerCodeDecoder
import net.dankito.banking.fints.tan.TanImageDecoder import net.dankito.banking.fints.tan.TanImageDecoder
import net.dankito.banking.fints.util.TanMethodSelector import net.dankito.banking.fints.util.TanMethodSelector
import net.dankito.utils.multiplatform.extensions.millisSinceEpochAtEuropeBerlin
import net.dankito.utils.multiplatform.extensions.minusDays import net.dankito.utils.multiplatform.extensions.minusDays
import net.dankito.utils.multiplatform.extensions.todayAtEuropeBerlin import net.dankito.utils.multiplatform.extensions.todayAtEuropeBerlin
import net.dankito.utils.multiplatform.extensions.todayAtSystemDefaultTimeZone import net.dankito.utils.multiplatform.extensions.todayAtSystemDefaultTimeZone
@ -237,7 +236,7 @@ open class FinTsJobExecutor(
|| (response.successful && (parameter.alsoRetrieveBalance == false || balance != null)) || (response.successful && (parameter.alsoRetrieveBalance == false || balance != null))
val fromDate = parameter.fromDate val fromDate = parameter.fromDate
?: parameter.account.countDaysForWhichTransactionsAreKept?.let { LocalDate.todayAtSystemDefaultTimeZone().minusDays(it) } ?: parameter.account.countDaysForWhichTransactionsAreKept?.let { LocalDate.todayAtSystemDefaultTimeZone().minusDays(it) }
?: bookedTransactions.minByOrNull { it.valueDate.millisSinceEpochAtEuropeBerlin }?.valueDate ?: bookedTransactions.minByOrNull { it.valueDate }?.valueDate
val retrievedData = RetrievedAccountData(parameter.account, successful, balance, bookedTransactions, unbookedTransactions, fromDate, parameter.toDate ?: LocalDate.todayAtEuropeBerlin(), response.internalError) val retrievedData = RetrievedAccountData(parameter.account, successful, balance, bookedTransactions, unbookedTransactions, fromDate, parameter.toDate ?: LocalDate.todayAtEuropeBerlin(), response.internalError)
return GetAccountTransactionsResponse(context, response, retrievedData, return GetAccountTransactionsResponse(context, response, retrievedData,

View File

@ -1,8 +1,7 @@
package net.dankito.banking.fints.messages.datenelemente.abgeleiteteformate package net.dankito.banking.fints.messages.datenelemente.abgeleiteteformate
import kotlinx.datetime.LocalDateTime import kotlinx.datetime.LocalTime
import net.codinux.log.logger import net.codinux.log.logger
import net.dankito.utils.multiplatform.extensions.of
import net.dankito.banking.fints.messages.Existenzstatus import net.dankito.banking.fints.messages.Existenzstatus
import net.dankito.banking.fints.messages.datenelemente.basisformate.ZiffernDatenelement import net.dankito.banking.fints.messages.datenelemente.basisformate.ZiffernDatenelement
import net.dankito.utils.multiplatform.extensions.toStringWithTwoDigits import net.dankito.utils.multiplatform.extensions.toStringWithTwoDigits
@ -23,11 +22,11 @@ open class Uhrzeit(time: Int?, existenzstatus: Existenzstatus) : ZiffernDatenele
private val log by logger() private val log by logger()
fun format(time: LocalDateTime): String { // parse to HbciTimeFormatString fun format(time: LocalTime): String { // parse to HbciTimeFormatString
return time.hour.toStringWithTwoDigits() + time.minute.toStringWithTwoDigits() + time.second.toStringWithTwoDigits() // TODO: is this correct? return time.hour.toStringWithTwoDigits() + time.minute.toStringWithTwoDigits() + time.second.toStringWithTwoDigits() // TODO: is this correct?
} }
fun parse(timeString: String): LocalDateTime { fun parse(timeString: String): LocalTime {
// do not use DateFormatter as Java DateFormat is not thread safe, resulting in a lot of curious errors in parallel execution // do not use DateFormatter as Java DateFormat is not thread safe, resulting in a lot of curious errors in parallel execution
if (timeString.length == 6) { if (timeString.length == 6) {
@ -36,7 +35,7 @@ open class Uhrzeit(time: Int?, existenzstatus: Existenzstatus) : ZiffernDatenele
val minute = timeString.substring(2, 4) val minute = timeString.substring(2, 4)
val second = timeString.substring(4, 6) val second = timeString.substring(4, 6)
return LocalDateTime.of(hour.toInt(), minute.toInt(), second.toInt()) return LocalTime(hour.toInt(), minute.toInt(), second.toInt())
} catch (e: Exception) { } catch (e: Exception) {
log.error(e) { "Could not parse time string '$timeString' to HBCI time" } log.error(e) { "Could not parse time string '$timeString' to HBCI time" }
} }
@ -46,8 +45,4 @@ open class Uhrzeit(time: Int?, existenzstatus: Existenzstatus) : ZiffernDatenele
} }
} }
constructor(time: LocalDateTime?, existenzstatus: Existenzstatus)
: this(time?.let { format(time).toInt() }, existenzstatus)
} }

View File

@ -1,7 +1,7 @@
package net.dankito.banking.fints.model package net.dankito.banking.fints.model
import kotlinx.datetime.LocalDate import kotlinx.datetime.LocalDate
import net.dankito.utils.multiplatform.extensions.atUnixEpochStart import net.dankito.utils.multiplatform.extensions.UnixEpochStart
open class AccountTransaction( open class AccountTransaction(
@ -45,7 +45,7 @@ open class AccountTransaction(
) { ) {
// for object deserializers // for object deserializers
internal constructor() : this(AccountData(), Money(Amount.Zero, ""), "", LocalDate.atUnixEpochStart, null, null, null, null, LocalDate.atUnixEpochStart) internal constructor() : this(AccountData(), Money(Amount.Zero, ""), "", UnixEpochStart, null, null, null, null, UnixEpochStart)
constructor(account: AccountData, amount: Money, unparsedReference: String, bookingDate: LocalDate, otherPartyName: String?, otherPartyBankCode: String?, otherPartyAccountId: String?, bookingText: String?, valueDate: LocalDate) constructor(account: AccountData, amount: Money, unparsedReference: String, bookingDate: LocalDate, otherPartyName: String?, otherPartyBankCode: String?, otherPartyAccountId: String?, bookingText: String?, valueDate: LocalDate)
: this(account, amount, false, unparsedReference, bookingDate, otherPartyName, otherPartyBankCode, otherPartyAccountId, bookingText, valueDate, : this(account, amount, false, unparsedReference, bookingDate, otherPartyName, otherPartyBankCode, otherPartyAccountId, bookingText, valueDate,

View File

@ -2,6 +2,7 @@ package net.dankito.banking.fints.response
import kotlinx.datetime.LocalDate import kotlinx.datetime.LocalDate
import kotlinx.datetime.LocalDateTime import kotlinx.datetime.LocalDateTime
import kotlinx.datetime.LocalTime
import kotlinx.datetime.atTime import kotlinx.datetime.atTime
import net.codinux.log.logger import net.codinux.log.logger
import net.dankito.banking.fints.log.IMessageLogAppender import net.dankito.banking.fints.log.IMessageLogAppender
@ -690,7 +691,7 @@ open class ResponseParser(
date = parseDate(dataElements[++dateIndex]) date = parseDate(dataElements[++dateIndex])
} }
var time: LocalDateTime? = null var time: LocalTime? = null
if (dataElements.size > dateIndex + 1) { if (dataElements.size > dateIndex + 1) {
try { try {
time = parseTime(dataElements[dateIndex + 1]) time = parseTime(dataElements[dateIndex + 1])
@ -1005,11 +1006,11 @@ open class ResponseParser(
return null return null
} }
protected open fun parseTime(timeString: String): LocalDateTime { protected open fun parseTime(timeString: String): LocalTime {
return Uhrzeit.parse(timeString) return Uhrzeit.parse(timeString)
} }
protected open fun parseNullableTime(timeString: String): LocalDateTime? { protected open fun parseNullableTime(timeString: String): LocalTime? {
try { try {
return parseTime(timeString) return parseTime(timeString)
} catch (ignored: Exception) { } } catch (ignored: Exception) { }

View File

@ -1,7 +1,7 @@
package net.dankito.banking.fints.response.segments package net.dankito.banking.fints.response.segments
import kotlinx.datetime.LocalDate import kotlinx.datetime.LocalDate
import kotlinx.datetime.LocalDateTime import kotlinx.datetime.LocalTime
import net.dankito.banking.fints.model.Amount import net.dankito.banking.fints.model.Amount
@ -9,7 +9,7 @@ open class Balance(
val amount: Amount, val amount: Amount,
val currency: String?, val currency: String?,
val date: LocalDate, val date: LocalDate,
val time: LocalDateTime? val time: LocalTime?
) { ) {
override fun toString(): String { override fun toString(): String {

View File

@ -1,8 +1,8 @@
package net.dankito.banking.fints.transactions.mt940.model package net.dankito.banking.fints.transactions.mt940.model
import kotlinx.datetime.LocalDate import kotlinx.datetime.LocalDate
import net.dankito.utils.multiplatform.extensions.atUnixEpochStart
import net.dankito.banking.fints.model.Amount import net.dankito.banking.fints.model.Amount
import net.dankito.utils.multiplatform.extensions.UnixEpochStart
open class Balance( open class Balance(
@ -42,7 +42,7 @@ open class Balance(
) { ) {
internal constructor() : this(false, false, LocalDate.atUnixEpochStart, "", Amount.Zero) // for object deserializers internal constructor() : this(false, false, UnixEpochStart, "", Amount.Zero) // for object deserializers
override fun toString(): String { override fun toString(): String {

View File

@ -2,6 +2,7 @@ package net.dankito.banking.fints.util
import kotlinx.datetime.LocalDate import kotlinx.datetime.LocalDate
import kotlinx.datetime.LocalDateTime import kotlinx.datetime.LocalDateTime
import kotlinx.datetime.LocalTime
import net.dankito.utils.multiplatform.extensions.nowAtEuropeBerlin import net.dankito.utils.multiplatform.extensions.nowAtEuropeBerlin
import net.dankito.utils.multiplatform.extensions.todayAtEuropeBerlin import net.dankito.utils.multiplatform.extensions.todayAtEuropeBerlin
import net.dankito.banking.fints.messages.datenelemente.abgeleiteteformate.Datum import net.dankito.banking.fints.messages.datenelemente.abgeleiteteformate.Datum
@ -29,10 +30,10 @@ open class FinTsUtils {
open fun formatTimeNow(): String { open fun formatTimeNow(): String {
return formatTime(LocalDateTime.nowAtEuropeBerlin()) return formatTime(LocalDateTime.nowAtEuropeBerlin().time)
} }
open fun formatTime(time: LocalDateTime): String { open fun formatTime(time: LocalTime): String {
return Uhrzeit.format(time) return Uhrzeit.format(time)
} }
@ -40,7 +41,7 @@ open class FinTsUtils {
return convertToInt(formatTimeNow()) return convertToInt(formatTimeNow())
} }
open fun formatTimeAsInt(time: LocalDateTime): Int { open fun formatTimeAsInt(time: LocalTime): Int {
return convertToInt(formatTime(time)) return convertToInt(formatTime(time))
} }

View File

@ -1,7 +1,7 @@
package net.dankito.banking.fints.messages package net.dankito.banking.fints.messages
import kotlinx.datetime.LocalDate import kotlinx.datetime.LocalDate
import kotlinx.datetime.LocalDateTime import kotlinx.datetime.LocalTime
import kotlinx.datetime.Month import kotlinx.datetime.Month
import net.dankito.banking.fints.FinTsTestBase import net.dankito.banking.fints.FinTsTestBase
import net.dankito.banking.fints.messages.datenelemente.implementierte.tan.JobTanConfiguration import net.dankito.banking.fints.messages.datenelemente.implementierte.tan.JobTanConfiguration
@ -22,7 +22,7 @@ class MessageBuilderTest : FinTsTestBase() {
return Date.toString() return Date.toString()
} }
override fun formatTime(time: LocalDateTime): String { override fun formatTime(time: LocalTime): String {
return Time.toString() return Time.toString()
} }
}) { }) {

View File

@ -1,8 +1,7 @@
package net.dankito.banking.fints.util package net.dankito.banking.fints.util
import kotlinx.datetime.LocalDate import kotlinx.datetime.LocalDate
import kotlinx.datetime.LocalDateTime import kotlinx.datetime.LocalTime
import net.dankito.utils.multiplatform.extensions.of
import kotlin.test.Test import kotlin.test.Test
import kotlin.test.assertEquals import kotlin.test.assertEquals
@ -42,7 +41,7 @@ class FinTsUtilsTest {
fun formatTime_AM() { fun formatTime_AM() {
// given // given
val time = LocalDateTime.of(8, 2, 1) val time = LocalTime(8, 2, 1)
// when // when
val result = underTest.formatTime(time) val result = underTest.formatTime(time)
@ -55,7 +54,7 @@ class FinTsUtilsTest {
fun formatTime_PM() { fun formatTime_PM() {
// given // given
val time = LocalDateTime.of(18, 22, 51) val time = LocalTime(18, 22, 51)
// when // when
val result = underTest.formatTime(time) val result = underTest.formatTime(time)
@ -68,7 +67,7 @@ class FinTsUtilsTest {
fun formatTimeAsInt_AM() { fun formatTimeAsInt_AM() {
// given // given
val time = LocalDateTime.of(8, 2, 1) val time = LocalTime(8, 2, 1)
// when // when
val result = underTest.formatTimeAsInt(time) val result = underTest.formatTimeAsInt(time)
@ -81,7 +80,7 @@ class FinTsUtilsTest {
fun formatTimeAsInt_PM() { fun formatTimeAsInt_PM() {
// given // given
val time = LocalDateTime.of(18, 22, 51) val time = LocalTime(18, 22, 51)
// when // when
val result = underTest.formatTimeAsInt(time) val result = underTest.formatTimeAsInt(time)

View File

@ -4,33 +4,8 @@ import kotlinx.datetime.*
import kotlin.js.JsName import kotlin.js.JsName
val LocalDate.Companion.atUnixEpochStart: LocalDate val UnixEpochStart: LocalDate = LocalDate.parse("1970-01-01")
get() = fromEpochMillisecondsAtUtc(0)
@JsName("dateFromEpochMillisecondsAtUtc")
fun LocalDate.Companion.fromEpochMillisecondsAtUtc(epochMilliseconds: Long): LocalDate {
return fromEpochMilliseconds(epochMilliseconds, TimeZone.UTC)
}
@JsName("dateFromEpochMillisecondsAtSystemDefaultTimeZone")
fun LocalDate.Companion.fromEpochMillisecondsAtSystemDefaultTimeZone(epochMilliseconds: Long): LocalDate {
return fromEpochMilliseconds(epochMilliseconds, TimeZone.currentSystemDefault())
}
@JsName("dateFromEpochMillisecondsAtEuropeBerlin")
fun LocalDate.Companion.fromEpochMillisecondsAtEuropeBerlin(epochMilliseconds: Long): LocalDate {
return fromEpochMilliseconds(epochMilliseconds, TimeZone.europeBerlin)
}
@JsName("dateFromEpochMilliseconds")
fun LocalDate.Companion.fromEpochMilliseconds(epochMilliseconds: Long, timeZone: TimeZone): LocalDate {
return Instant.fromEpochMilliseconds(epochMilliseconds).toLocalDateTime(timeZone).date
}
fun LocalDate.Companion.todayAtUtc(): LocalDate {
return nowAt(TimeZone.UTC)
}
fun LocalDate.Companion.todayAtSystemDefaultTimeZone(): LocalDate { fun LocalDate.Companion.todayAtSystemDefaultTimeZone(): LocalDate {
return nowAt(TimeZone.currentSystemDefault()) return nowAt(TimeZone.currentSystemDefault())
@ -40,40 +15,12 @@ fun LocalDate.Companion.todayAtEuropeBerlin(): LocalDate {
return nowAt(TimeZone.europeBerlin) return nowAt(TimeZone.europeBerlin)
} }
@JsName("nowAtForTimeZoneStringForDate")
fun LocalDate.Companion.nowAt(timeZone: String): LocalDate {
return nowAt(TimeZone.of(timeZone))
}
@JsName("nowAtForDate") @JsName("nowAtForDate")
fun LocalDate.Companion.nowAt(timeZone: TimeZone): LocalDate { fun LocalDate.Companion.nowAt(timeZone: TimeZone): LocalDate {
return Clock.System.todayIn(timeZone) return Clock.System.todayIn(timeZone)
} }
val LocalDate.millisSinceEpochAtUtc: Long
get() = this.toEpochMillisecondsAt(TimeZone.UTC)
val LocalDate.millisSinceEpochAtSystemDefaultTimeZone: Long
get() = this.toEpochMillisecondsAt(TimeZone.currentSystemDefault())
val LocalDate.millisSinceEpochAtEuropeBerlin: Long
get() = this.toEpochMillisecondsAt(TimeZone.europeBerlin)
@JsName("toEpochMillisecondsAtForDate")
fun LocalDate.toEpochMillisecondsAt(timeZone: TimeZone): Long {
return this.toLocalDateTime().toInstant(timeZone).toEpochMilliseconds()
}
fun LocalDate.toLocalDateTime(): LocalDateTime {
return this.atTime(0, 0)
}
fun LocalDate.addDays(days: Int): LocalDate {
return this.plus(days, DateTimeUnit.DAY)
}
fun LocalDate.minusDays(days: Int): LocalDate { fun LocalDate.minusDays(days: Int): LocalDate {
return this.minus(days, DateTimeUnit.DAY) return this.minus(days, DateTimeUnit.DAY)
} }

View File

@ -1,61 +1,17 @@
package net.dankito.utils.multiplatform.extensions package net.dankito.utils.multiplatform.extensions
import kotlinx.datetime.* import kotlinx.datetime.*
import kotlin.js.JsName
fun LocalDateTime.Companion.of(hour: Int, minute: Int, second: Int = 0, nanosecond: Int = 0): LocalDateTime {
return LocalDateTime(0, 1, 1, hour, minute, second, nanosecond) // minimum values for month and day are 1
}
fun LocalDateTime.Companion.fromEpochMillisecondsAtUtc(epochMilliseconds: Long): LocalDateTime {
return fromEpochMilliseconds(epochMilliseconds, TimeZone.UTC)
}
fun LocalDateTime.Companion.fromEpochMillisecondsAtSystemDefaultTimeZone(epochMilliseconds: Long): LocalDateTime {
return fromEpochMilliseconds(epochMilliseconds, TimeZone.currentSystemDefault())
}
fun LocalDateTime.Companion.fromEpochMillisecondsAtEuropeBerlin(epochMilliseconds: Long): LocalDateTime {
return fromEpochMilliseconds(epochMilliseconds, TimeZone.europeBerlin)
}
fun LocalDateTime.Companion.fromEpochMilliseconds(epochMilliseconds: Long, timeZone: TimeZone): LocalDateTime {
return Instant.fromEpochMilliseconds(epochMilliseconds).toLocalDateTime(timeZone)
}
fun LocalDateTime.Companion.nowAtUtc(): LocalDateTime { fun LocalDateTime.Companion.nowAtUtc(): LocalDateTime {
return nowAt(TimeZone.UTC) return nowAt(TimeZone.UTC)
} }
fun LocalDateTime.Companion.nowAtSystemDefaultTimeZone(): LocalDateTime {
return nowAt(TimeZone.currentSystemDefault())
}
fun LocalDateTime.Companion.nowAtEuropeBerlin(): LocalDateTime { fun LocalDateTime.Companion.nowAtEuropeBerlin(): LocalDateTime {
return nowAt(TimeZone.europeBerlin) return nowAt(TimeZone.europeBerlin)
} }
@JsName("nowAtForTimeZoneString")
fun LocalDateTime.Companion.nowAt(timeZone: String): LocalDateTime {
return nowAt(TimeZone.of(timeZone))
}
fun LocalDateTime.Companion.nowAt(timeZone: TimeZone): LocalDateTime { fun LocalDateTime.Companion.nowAt(timeZone: TimeZone): LocalDateTime {
return Clock.System.now().toLocalDateTime(timeZone) return Clock.System.now().toLocalDateTime(timeZone)
}
//val LocalDateTime.millisSinceEpochAtUtc: Long
// get() = this.toEpochMillisecondsAt(TimeZone.UTC)
//
//val LocalDateTime.millisSinceEpochAtSystemDefaultTimeZone: Long
// get() = this.toEpochMillisecondsAt(TimeZone.currentSystemDefault())
//
//val LocalDateTime.millisSinceEpochAtEuropeBerlin: Long
// get() = this.toEpochMillisecondsAt(TimeZone.europeBerlin)
fun LocalDateTime.toEpochMillisecondsAt(timeZone: TimeZone): Long {
return this.toInstant(timeZone).toEpochMilliseconds()
} }