【问题标题】:Start and End of Week w/ ThreeTenBackport使用 ThreeTenBackport 开始和结束一周
【发布时间】:2019-11-06 15:17:23
【问题描述】:

我目前正在将 Joda-Time 的一些代码更改为使用 Three-Ten Android Backport。

以下所有方法都将long 作为参数并返回long

使用 JodaTime 获得一周的结束和开始对于 Joda-Time 来说是直截了当的:

LocalDate(long time).dayOfWeek().withMaximumValue()
LocalDate(long time).dayOfWeek().withMinimumValue()

一天的结束和开始也存在同样的问题,Joda-Time:

DateTime(long time).withTimeAtStartOfDay().getMillis() + DateUtils.DAY_IN_MILLIS - 1
DateTime(long time).withTimeAtStartOfDay().getMillis()

但是我不明白如何以这种方式使用threeTenAbp。

一天的结束和开始的想法:

一天结束:

LocalDateTime dt = DateTimeUtils.toLocalDateTime(new Timestamp(time));
ZonedDateTime zdt = ZonedDateTime.of(dt, ZoneId.systemDefault());
return zdt.with(LocalTime.MAX).toEpochSecond();

一天的开始:

LocalDateTime dt = DateTimeUtils.toLocalDateTime(new Timestamp(long time));
ZonedDateTime zdt = ZonedDateTime.of(dt, ZoneId.systemDefault());
return zdt.toLocalDate().atStartOfDay(ZoneId.systemDefault()).toEpochSecond();

这似乎很复杂,并没有真正为我提供任何线索,告诉我如何获取与传递给函数的long time 相对应的一周开始和结束的时间。

【问题讨论】:

  • 既然您正在重写,我建议:(1) 停止使用long 来表示日期和时间。使用适当的日期时间对象。 (2)不要得到一天的结束(那一刻无论如何都不存在)。取而代之的是第二天的开始。了解半开区间。
  • 顺便说一句,您不想将 Joda-Time 的 DateTime 替换为 LocalDateTime。考虑ZonedDateTime。或OffsetDateTime。而且你不想引入过时的Timestamp 类。

标签: android datetime jodatime threetenbp


【解决方案1】:

为了获得一天的开始和结束,我将使用with() 方法,传入预定义的LocalTime 实例之一:

LocalDateTime ldt = LocalDateTime.now();
LocalDateTime startOfDay = ldt.with(LocalTime.MIN); // 00:00:00
LocalDateTime endOfDay = ldt.with(LocalTime.MAX); // 23:59:59

要获得一周的第一天和最后一天,您可以执行相同的操作,但您必须首先定义“一周”的含义。一些地区认为一周从星期一开始,而另一些地区则认为一周从星期日开始。

在美国,星期从星期日开始。我们可以通过使用WeekFields.of() 来获得代表此内容的TemporalField

WeekFields usWeek = WeekFields.of(Locale.US);

然后我们可以通过将该字段分别设置为17 来获取一周的第一天和最后一天:

LocalDateTime firstDayOfWeek = ldt.with(usWeek.dayOfWeek(), 1);
LocalDateTime lastDayOfWeek = ldt.with(usWeek.dayOfWeek(), 7);

【讨论】:

    【解决方案2】:

    我们没有得到全貌,所以我的建议可能不是重点,但让我尝试一下。

        long millisSinceEpoch = 1_555_555_555_555L;
        LocalDate date = Instant.ofEpochMilli(millisSinceEpoch)
                .atZone(ZoneId.systemDefault())
                .toLocalDate();
        LocalDate firstDayOfWeek = date.with(DayOfWeek.MONDAY);
        LocalDate lastDayOfWeek = date.with(DayOfWeek.SUNDAY);
        System.out.println("Week is from " + firstDayOfWeek + " through " + lastDayOfWeek);
    

    周是从 2019-04-15 到 2019-04-21

    我假设您想要 ISO 周,也就是说,星期一是一周的第一天(我认为这是您的 Joda-Time 代码给您的)。如果没有,您需要在 Ben P. 的回答中引入 WeekFields 对象。我建议您不要转换回longLocalDate 更适合继续工作。

    一天的开始:

        ZonedDateTime startOfDay = date.atStartOfDay(ZoneId.systemDefault());
        System.out.println("Start of day: " + startOfDay);
    

    在我的时区,我得到:

    一天开始:2019-04-18T00:00+02:00[欧洲/哥本哈根]

    同样,保留您的 ZonedDateTime 对象,而不是转换为毫秒。

    不要计算一天的结束。对于一天结束的时间点(“午夜”),请始终使用一天的开始。

        ZonedDateTime startOfNextDay = date.plusDays(1)
                .atStartOfDay(ZoneId.systemDefault());
        System.out.println("Day is from " + startOfDay + " inclusive to " + startOfNextDay + " exclusive");
    

    日期从 2019-04-18T00:00+02:00[Europe/Copenhagen] 到 2019-04-19T00:00+02:00[欧洲/哥本哈根]独家

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2016-02-03
      • 2023-03-30
      • 2018-10-05
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-07-25
      相关资源
      最近更新 更多