【发布时间】:2021-10-02 14:23:00
【问题描述】:
我有两个时间戳和一个本地化日期,用于查找时区偏移并将其添加到这些日期。如何更简单地计算日期之间的时间偏移?我的方法不适用于负值(if (tsOffset.toSecondOfDay() > 0 总是true)。
fun parseDateTime(startTs: Long, endTs: Long, localizedDateTime: String): Pair<String, String> {
val dateUtcStart = LocalDateTime.ofInstant(Instant.ofEpochMilli(startTs), ZoneOffset.UTC)
val dateUtcEnd = LocalDateTime.ofInstant(Instant.ofEpochMilli(endTs), ZoneOffset.UTC)
val formatter = DateTimeFormatterBuilder()
.parseCaseInsensitive()
.parseDefaulting(ChronoField.YEAR_OF_ERA, dateUtcStart.year.toLong())
.append(DateTimeFormatter.ofPattern("E dd MMM hh:mm a"))
.toFormatter(Locale.ENGLISH)
val localDateTime = LocalDateTime.parse(localizedDateTime, formatter)
val localTs = Timestamp.valueOf(localDateTime).time
val tsOffset = LocalTime.ofInstant(Instant.ofEpochMilli(localTs - startTs), ZoneOffset.systemDefault())
val tzString = if (tsOffset.toSecondOfDay() > 0) "+$tsOffset" else tsOffset.toString()
val startDate = dateUtcStart.toString() + tzString
val endDate = dateUtcEnd.toString() + tzString
return Pair(startDate, endDate)
}
@Test
fun parseDateTime() {
val pair1 = parseDateTime(1626998400000, 1627005600000, "Fri 23 Jul 10:30 am")
val pair2 = parseDateTime(1626998400000, 1627005600000, "Thu 22 Jul 11:30 pm")
// pass
assertEquals("2021-07-23T00:00+10:30", pair1.first)
assertEquals("2021-07-23T02:00+10:30", pair1.second)
// fails
assertEquals("2021-07-23T00:00-00:30", pair2.first)
assertEquals("2021-07-23T02:00-00:30", pair2.second)
}
我也试过了
val dur = Duration.between(dateUtcStart, localDateTime)
但不确定如何在字符串中转换或正确添加到日期。
这里startTs - 事件时间戳的开始。 endTs - 此事件时间戳的结束。 localizedDateTime 用于显示实际时区(真实城市)的开始时间,而时间戳则以 UTC 显示时间。我需要从 localizedDateTime 中提取这个时区,并将其添加到开始和结束字符串 dateTimes(start = "2021-07-23T00:00+10:30", end = "2021-07-23T02:00+10:30" 对应于 startTs = 1626998400000 和 endTs = 1627005600000)。
【问题讨论】:
-
我对您的
localizedDateTime: String输入的角色感到困惑。该字符串只是一个日期和一天中的时间,没有时区的上下文或与 UTC 的偏移量。然而,您似乎认为它代表某个时区的某个时刻。您的代码中可能存在一些严重的缺陷。特别是,您对LocalDateTime和Timestamp类的使用令人不安。我建议您编辑您的问题,以更清楚地解释您的原始问题/目标,而不是关注您的代码。仔细而准确地指定输入的每个元素代表什么,以及您想要输出什么。 -
localizedDateTime用于显示实际时区(真实城市)的时间,而时间戳以 UTC 显示时间。所有这些都是第 3 方输入,我无法更改它们。我的问题是:我只有这 3 个日期,并且需要像在测试中一样使用时区偏移来创建开始和结束日期(例如2021-07-23T00:00+10:30) -
将澄清作为对您问题的编辑而不是作为评论发布。
-
@Psijic 更新您的问题以描述所有这些混乱在做什么 - 因为您的代码没有帮助,因为它到处都是并且滥用 java.time 类型。你想做什么-? “开始”和“结束”分别代表什么?那个时间代表什么?示例更新:“输入 A 和 B 是 epoch-millis。输入 C 是一个字符串,表示与 epoch-milli A 在同一时刻的时间,在某个未知时区。此方法应派生该时区,然后渲染 epoch-milli A 和 B 在该时区具有硬编码格式。如果不可能,则抛出异常 X。
-
我认为
startTs(等于2021-07-23T00:00:00Z UTC)和localizedDateTime应该表示相同的时间点,我们需要计算UTC抵消这些信息?但是要使结果开始日期和时间相等,它肯定需要是2021-07-23T10:30+10:30,而不是2021-07-23T00:00+10:30。我错过了什么?