使用 joda time 提取秒数直到午夜

Extracting the seconds until midnight with joda time

我有两个时间戳。 (开始和结束)一个时间戳可能是昨天的。 如果发生这种情况,我想知道直到中午 12 点(直到这一天切换到今天)之前的确切秒数,然后是直到当前时间戳的其余时间。 也有可能开始日期是几天前,那么我想要从一天到另一天的秒数,直到今天。

我觉得这可以使用 joda time 最有效地完成,但不知道如何做。 感谢

**Example**

Start: timestamp(yesterday 23.55)
End: timestamp(today 00.02)

Should Return:
 Date of yesterday: 300 seconds
 Date of today: 120 seconds.

Another example:
Start date: timestamp( day before yesterday 23.58)
End date: timestamp(00.02)

Should return:
 Date of day before yesterday: 120 seconds
 Yesterday: 86400 seconds
 Today: 120 seconds

请注意,您不需要 "midnight",您需要 "start of day" - 这是一个细微的差别,但在某些时区,某些日子,没有午夜。

假设您的时间戳在 DateTime 个具有适当时区的实例中:

DateTime startOfDay = end.withTimeAtStartOfDay();
if (startOfDay.isAfter(start)) {
  // startOfDay is after start, meaning that start and end are on different days.
  Seconds secondsBeforeSod = Seconds.secondsBetween(start, startOfDay);
  Seconds secondsAfterSod = Seconds.secondsBetween(startOfDay, end);
}

是这样的吗?它正确处理 DST 切换期间没有午夜的时区。

private static void listSecondsPerDayBetween(DateTime from, DateTime to) {
    System.out.println(from.toString("yyyy-MM-dd HH:mm:ss") + " - " + to.toString("yyyy-MM-dd HH:mm:ss"));
    if (! from.isBefore(to))
        throw new IllegalArgumentException("Values are inverted: " + from + ", " + to);
    LocalDate date = from.toLocalDate().plusDays(1);
    DateTime nextMidnight = date.toDateTimeAtStartOfDay();
    DateTime prev = from;
    while (nextMidnight.isBefore(to)) {
        Seconds seconds = Seconds.secondsBetween(prev, nextMidnight);
        System.out.println("  " + prev.toString("yyyy-MM-dd") + "  " + seconds.getSeconds() + " seconds");
        prev = nextMidnight;
        date = date.plusDays(1);
        nextMidnight = date.toDateTimeAtStartOfDay();
    }
    Seconds seconds = Seconds.secondsBetween(prev, to);
    System.out.println("  " + prev.toString("yyyy-MM-dd") + "  " + seconds.getSeconds() + " seconds");
}

测试

listSecondsPerDayBetween(DateTime.parse("2016-01-31T23:55:00"),
                         DateTime.parse("2016-02-01T00:02:00"));
System.out.println();
listSecondsPerDayBetween(DateTime.parse("2016-02-01T09:45:00"),
                         DateTime.parse("2016-02-01T11:13:00"));
System.out.println();
listSecondsPerDayBetween(DateTime.parse("2016-03-11T23:55:00"),
                         DateTime.parse("2016-03-15T00:02:00"));

输出

2016-01-31 23:55:00 - 2016-02-01 00:02:00
  2016-01-31  300 seconds
  2016-02-01  120 seconds

2016-02-01 09:45:00 - 2016-02-01 11:13:00
  2016-02-01  5280 seconds

2016-03-11 23:55:00 - 2016-03-15 00:02:00
  2016-03-11  300 seconds
  2016-03-12  86400 seconds
  2016-03-13  82800 seconds
  2016-03-14  86400 seconds
  2016-03-15  120 seconds

请注意 3 月 13 日因为夏令时而变短了。