我有两个字符串作为startDate和endDate。这些值如下所示,例如:
startDate="2019-09-29T06:00:00.000Z"
endDate="2019-10-06T05:59:59.999Z"
现在让我们说,这些都是在山区时间作为startDate一天的开始和endDate一天的结束。但由于这些是字符串,我如何让程序理解这些字符串可以转换为山区当地时间,如:
startDate="2019-09-29T00:00:00.000Z"
endDate="2019-10-05T11:59:59.999Z"
时区是html" target="_blank">动态的。我可以从东部时间或任何其他时区获得时间戳字符串。
更新
我意识到我应该输入更多的信息。
所以我输入的Moutain时间就是一个例子。它可以来自东部时间或任何其他时区。此方法知道的唯一事实是,starDate是某个时区中一天的开始,endDate是该时区中一天的结束。我知道'Z'是世界协调时,但找出哪个时区在一天的开始(开始日期)和一天的结束(结束日期)产生了世界协调时,并转换回相应的本地时间,是我面临的挑战。
我的手指离不开这个,很有趣。据我所知,你不知道开始和结束字符串来自哪个时区,它可以是任何时区。我们能做什么,除了轮流尝试它们?
String startDate = "2019-09-29T06:00:00.000Z";
String endDate = "2019-10-06T05:59:59.999Z";
LocalTime dayStart = LocalTime.MIN;
LocalTime dayEndEarliset = LocalTime.of(23, 59, 59);
Instant startInstant = Instant.parse(startDate);
Instant endInstant = Instant.parse(endDate);
// Just out of curiosity find candidate time zones
Set<ZoneId> candidateZones = ZoneId.getAvailableZoneIds()
.stream()
.map(ZoneId::of)
.filter(zid -> startInstant.atZone(zid).toLocalTime().equals(dayStart)
&& ! endInstant.atZone(zid).toLocalTime().isBefore(dayEndEarliset))
.collect(Collectors.toSet());
System.out.println("Potential time zones: " + candidateZones);
// Real work: find candidate date(s)
Set<LocalDate> candidateDates = ZoneId.getAvailableZoneIds()
.stream()
.map(ZoneId::of)
.filter(zid -> startInstant.atZone(zid).toLocalTime().equals(dayStart)
&& ! endInstant.atZone(zid).toLocalTime().isBefore(dayEndEarliset))
.map(zid -> startInstant.atZone(zid).toLocalDate())
.collect(Collectors.toSet());
if (candidateDates.isEmpty()) {
System.out.println("Cannot identify a date from the instants");
} else if (candidateDates.size() > 1) {
System.out.println("Ambiguous date, candidates are " + candidateDates);
} else {
System.out.println("The date is " + candidateDates.iterator().next());
}
这张照片是:
Potential time zones: [America/Inuvik, America/Yellowknife, America/Regina, America/Boise, SystemV/MST7MDT, America/El_Salvador, America/Costa_Rica, America/Shiprock, America/Guatemala, America/Denver, America/Belize, America/Swift_Current, America/Managua, Mexico/BajaSur, Canada/Mountain, America/Cambridge_Bay, Navajo, America/Chihuahua, America/Ojinaga, MST7MDT, Pacific/Galapagos, America/Mazatlan, US/Mountain, America/Edmonton, America/Tegucigalpa, Canada/Saskatchewan, Etc/GMT+6, SystemV/CST6]
The date is 2019-09-29
是的,美国/丹佛是预期的候选时区之一。到目前为止,我已经找到了开始日期。您可以以类似的方式找到开始日期和结束日期对。您可能更喜欢老式的循环,而不是流操作。
然而,日期并不总是明确的。让我们试着在太平洋/Pago_Pago时区构造一天的间隔。它在偏移-11:00。
ZoneId zone = ZoneId.of("Pacific/Pago_Pago");
LocalDate testDate = LocalDate.of(2019, Month.OCTOBER, 2);
String startDate = testDate.atStartOfDay(zone).toInstant().toString();
String endDate = testDate.atTime(LocalTime.of(23, 59, 59, 999_000_000))
.atZone(zone)
.toInstant()
.toString();
现在程序的输出为:
Potential time zones: [Antarctica/McMurdo, Pacific/Niue, Pacific/Samoa, Pacific/Tongatapu, Pacific/Enderbury, Etc/GMT+11, NZ, Antarctica/South_Pole, Etc/GMT-13, Pacific/Pago_Pago, Pacific/Midway, Pacific/Fakaofo, US/Samoa, Pacific/Auckland]
Ambiguous date, candidates are [2019-10-03, 2019-10-02]
这是因为也有偏移13:00的时区。我们可以判断偏移量一定是-11:00或13:00,但我们无法判断两者中的哪一个。所以两个日期出来了。
使用半开放的时间间隔
我不确定结尾是否总是在有关时区的23:59:59.999,或者有时可能是23:59:59.999999或其他什么。此外,无论我们添加多少小数,理论上仍然存在在结束时间之后但仍在同一日期内的时刻。在代码中,我保守地接受23:59:59及以后的任何时间作为结束时间。完全避免疑问的要点是:使用半开区间。将间隔的开始表示为00:00:00,并将结束表示为最后一个日期之后的日期中的00:00:00。并将开始日期视为包容性,将结束视为排他性。
末尾的Z
是时区信息,意味着从UTC,也称为零,也称为Zulu的偏移量00:00,因此首先将字符串解析为存储日期、时间和Z
时区的类型。
使用Java 8时间API,这将是即时
,偏移日期时间
,或分区日期时间
如果您的输入总是以Z
结束,而不是其他偏移,请使用即时
。
然后,您将转换到所需的时区,对于我们来说,山区时间称为美国/丹佛
。
实例
String startDate = "2019-09-29T06:00:00.000Z";
String endDate = "2019-10-06T05:59:59.999Z";
ZoneId zone = ZoneId.of("America/Denver");
System.out.println(Instant.parse(startDate).atZone(zone));
System.out.println(OffsetDateTime.parse(startDate).atZoneSameInstant(zone));
System.out.println(ZonedDateTime.parse(startDate).withZoneSameInstant(zone));
System.out.println(Instant.parse(endDate).atZone(zone));
System.out.println(OffsetDateTime.parse(endDate).atZoneSameInstant(zone));
System.out.println(ZonedDateTime.parse(endDate).withZoneSameInstant(zone));
输出
2019-09-29T00:00-06:00[America/Denver]
2019-09-29T00:00-06:00[America/Denver]
2019-09-29T00:00-06:00[America/Denver]
2019-10-05T23:59:59.999-06:00[America/Denver]
2019-10-05T23:59:59.999-06:00[America/Denver]
2019-10-05T23:59:59.999-06:00[America/Denver]
如果您不想在转换后保留时区,可以通过调用toLocalDateTime()
将其删除,例如。
System.out.println(Instant.parse(endDate).atZone(zone).toLocalDateTime());
输出
2019-10-05T23:59:59.999
注意,它的末尾没有一个Z
。
问题内容: 我想检查日期是否在开始日期和结束日期之间。 我添加了一个where子句 但问题在于它不包含“ 2010-04-15”。 它应该包括结束日期,我该怎么办? 请帮我 问候, 潘卡 问题答案: 明确指定时间部分:
问题内容: 如果可能的话,在以下情况下,我希望使用joda或非joda解决方案 假设我的一周从2012年5月2日开始,给定的当前日期为02/22/2011。我需要计算给定当前日期的星期开始和结束日期。因此,我的解决方案的星期应该从02/19开始,而星期在02/25结束。为简单起见,我将我的工作日设置为02/05/2011,但是可能是任何一天,我的工作日始终为7天。 我现有的代码如下,但似乎无法按预
我想在日期时间选择器中选择大于开始日期的结束日期时间。 当前,我正在开始日期时间和结束日期时间。 假设,我选择了时间为12:00 pm的当前日期,现在end date应该是时间为1:00 pm的当前日期。 我想要下面这样的东西 示例 开始日期和时间:---2019-11-06 12:00结束日期和时间:---2019-11-06 1:00 这是我的代码 null null
我试图找出明星日期和结束日期的员工时钟。以下是我所掌握的数据示例。 需要输出: 我必须根据eventtime和activitycode找到此人的开始日期和结束日期。开始日期将是事件时间列,我必须从行中下一个事件时间的同一列计算结束日期。 我曾尝试在T-SQL中使用lead函数,但它并没有给出我想要的结果。 如果有人知道如何处理这个问题,我会非常感激。
问题内容: 我有一个事件表,其中记录了一个开始和结束时间,作为MySQL DATETIME对象(格式。我想查找在特定日期范围内发生的所有事件。但是,事件可能跨越多天(并且超出了我的范围)日期范围,但是如果它们与我的日期范围重叠1秒或更长时间,我想返回它们。 有什么建议吗? 问题答案: 这将找到范围内完全包含的每个事件: 这将查找事件的任何部分与范围的任何部分重叠的任何事件:
问题内容: 我有一张关于不同资产的开/关事件的表格。我需要在不使用游标的情况下获取开始和停止事件时间的列表。 来源: 所需结果: 问题答案: 这是解决方案,带有概念验证供所有人验证。 我注意到的事件被标记为新事件。我解决了这个问题,但是这也导致我编写了一个解决方案,该解决方案允许发生一个已经开始但尚未结束的事件,因此我加入了一个开放式事件。 另外,我的解决方案在重叠的时期内有效。 讲解 我们将数据