【问题标题】:How to get start time and end time of a day in another timezone in Android如何在Android的另一个时区获取一天的开始时间和结束时间
【发布时间】:2020-09-25 20:32:48
【问题描述】:

我的日期格式为:YYYY-MM-DD

所需的输出格式为: "yyyy-MM-dd'T'HH:mm:ss.SSS'Z'"

我想在 美国/芝加哥获取 ISO 格式的日期作为一天的开始时间(从上午 12:00 开始)和一天的结束时间(结束于晚上 11:59)时区。

例如。对于日期:2020-06-08(6 月 8 日),转换后的最终输出如下:

一天的开始时间为日期:2020-06-08T05:00:00.000Z

一天中的结束时间为日期:2020-06-09T04:59:59.999Z

如果有人对此有任何线索,请在这里帮助我。

答案: http://m.uploadedit.com/bltc/1591511729781.txt

【问题讨论】:

  • 您的日期字符串没有时间。开始时间和结束时间中的时间部分来自哪里?
  • 正如我所说,我想将日期转换为一天的开始时间 (12:00:00AM) 和一天的结束时间 (11:59:59PM)

标签: java android date time date-conversion


【解决方案1】:

java.time 和 ThreeTenABP

我建议使用现代 Java 日期和时间 API java.time 来计算日期和时间。

    ZoneId zone = ZoneId.of("America/Chicago");

    String dateString = "2020-06-08";
    LocalDate date = LocalDate.parse(dateString);
    Instant startOfDay = date.atStartOfDay(zone).toInstant();
    Instant endOfDay = date.plusDays(1).atStartOfDay(zone).toInstant();

    System.out.println("The day is from " + startOfDay + " (inclusive) to " + endOfDay + " (exclusive)");

输出是:

这一天从2020-06-08T05:00:00Z(含)到 2020-06-09T05:00:00Z(独家)

为了不排除一天的最后一毫秒,我们需要将这一天计算为持续到第二天的第一时刻。如果你坚持要减去一毫秒或一纳秒,当然,这取决于你。例如:

    Instant endOfDay = date.plusDays(1).atStartOfDay(zone).minusNanos(1).toInstant();

这一天从2020-06-08T05:00:00Z(含)到 2020-06-09T04:59:59.999999999Z(包括 1 纳米以上)

编辑:如何在输出中打印毫秒?你很可能不需要那个。您要求的格式是国际标准 ISO 8601(请参阅底部的链接)。在 ISO 8601 中,秒的分数是可选的,省略它意味着 0。所以任何需要 ISO 8601 的 API 都应该接受上述内容。只有在没有的情况下,正确的解决方案是使用格式化程序。在这种情况下,我们需要将时间显式转换为 UTC:

    ZoneId zone = ZoneId.of("America/Chicago");
    DateTimeFormatter formatterWithMillis = DateTimeFormatter.ofPattern("uuuu-MM-dd'T'HH:mm:ss.SSSX");

    String dateString = "2020-06-08";
    LocalDate date = LocalDate.parse(dateString);
    OffsetDateTime startOfDay = date.atStartOfDay(zone)
            .toOffsetDateTime()
            .withOffsetSameInstant(ZoneOffset.UTC);
    OffsetDateTime endOfDay = date.plusDays(1)
            .atStartOfDay(zone)
            .toOffsetDateTime()
            .withOffsetSameInstant(ZoneOffset.UTC);

    String startString = startOfDay.format(formatterWithMillis);
    String endString = endOfDay.format(formatterWithMillis);
    System.out.println("The day is from " + startString + " (inclusive) to " + endString + " (exclusive)");

这一天是从2020-06-08T05:00:00.000Z(含)到 2020-06-09T05:00:00.000Z(独家)

或者像以前一样从结束时间减去一纳秒后:

    OffsetDateTime endOfDay = date.plusDays(1)
            .atStartOfDay(zone)
            .minusNanos(1)
            .toOffsetDateTime()
            .withOffsetSameInstant(ZoneOffset.UTC);

这一天是从2020-06-08T05:00:00.000Z(含)到 2020-06-09T04:59:59.999Z(包括和 1 纳米以上)

(由于时间被截断为整毫秒,1 nano more 并没有真正意义,但我认为这不是重点。)

问题:java.time 不需要 Android API 26 级吗?

java.time 在较旧和较新的 Android 设备上都能很好地工作。它只需要至少 Java 6

  • 在 Java 8 及更高版本以及更新的 Android 设备(从 API 级别 26 起)中,现代 API 是内置的。
  • 在非 Android 的 Java 6 和 7 中,获取 ThreeTen Backport,这是现代类的后向端口(对于 JSR 310,ThreeTen;请参阅底部的链接)。
  • 在(较旧的)Android 上使用 ThreeTen Backport 的 Android 版本。它被称为 ThreeTenABP。并确保从 org.threeten.bp 导入日期和时间类以及子包。

但是除了切换到 ThreeTenBP 之外,我们没有其他选择吗? 图书馆?

如果你坚持,我想可以找到使用CalendarDateSimpleDateFormat的方法。这些类设计不佳且早已过时,因此根据我所知道和不知道的情况,我更喜欢 ThreeTenABP。

链接

【讨论】:

    【解决方案2】:

    更新:

        ZoneId zoneId = ZoneId.of("America/Chicago");
        LocalDate localDate = LocalDate.parse("2020-06-08");
        DateTimeFormatter newPattern = DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:mm:ss.SSS'Z'").withZone(zoneId);
        Instant startOfDay = localDate.atStartOfDay(zoneId).toInstant();
        Instant endOfDay = LocalDateTime.of(localDate, LocalTime.MAX).atZone(zoneId).toInstant().truncatedTo(ChronoUnit.MILLIS);
        System.out.println(startOfDay);
        System.out.println(endOfDay);
    

    根据我所经历的,小数 000 不会出现在其中,但是可以肯定的是,如果没有毫秒的小数,那么它就是 000。我无法弄清楚如何在格式化时带上这个. 如果您找到了一些东西,请添加其他内容,您可以通过将 startDate 转换为 String 然后将 000 附加到它来做到这一点。

    结果

        2020-06-08T05:00:00Z
        2020-06-09T04:59:59.999Z
    

    【讨论】:

    • 谢谢 Sunil,我们可以得到这种格式的输出吗:“yyyy-MM-dd'T'HH:mm:ss.SSS'Z'”
    • 是的,实际上 SSS'Z 中所需字符串的最后一部分,而在您的输出字符串开始日期中没有它(虽然需要 000Z)并且结束日期有它像 999999999Z(虽然需要999Z)
    • 如果这解决了您的问题,请接受它作为答案
    • @sunil,运行代码后,输出不是我所期望的:我写下了这样的代码:m.uploadedit.com/bltc/159150652274.TXT
    • @OleV.V.您的解决方案似乎正在处理一个小改动m.uploadedit.com/bltc/1591511729781.txt
    猜你喜欢
    • 1970-01-01
    • 2016-07-02
    • 2015-03-29
    • 1970-01-01
    • 2021-01-19
    • 1970-01-01
    • 2023-02-26
    • 1970-01-01
    • 2014-10-22
    相关资源
    最近更新 更多