假设我希望我的一周从星期二开始,这一天应该从早上 5:30 开始。
这意味着,像这样的代码应该可以工作:
// LocalDateTimes created with the "standard" ISO time
LocalDateTime tuesday_4_30 = LocalDateTime.now()
.with(TemporalAdjusters.next(DayOfWeek.TUESDAY))
.withHour(4).withMinute(30);
LocalDateTime tuesday_6_30 = tuesday_4_30.withHour(6).withMinute(30);
LocalDateTime previous_monday = tuesday_4_30.minusDays(1);
// eventual adjustment using TemporalAdjusters here? like this?
// tuesday_4_30 = tuesday_4_30.with(new MyTemporalAdjuster(DayOfWeek.TUESDAY, 5, 30));
// <do the same for 6_30 and previous monday>
// or possibly change some global parameter like Chronology, Locale, or such..
Assert.assertEquals(tuesday_4_30.getDayOfWeek(), DayOfWeek.MONDAY);
Assert.assertEquals(tuesday_6_30.getDayOfWeek(), DayOfWeek.TUESDAY);
// there is 1 week between the previous monday and the next tuesday 6:30
Assert.assertEquals( ChronoUnit.WEEKS.between(previous_monday,tuesday_6_30), 1);
// there is 0 week between the previous monday and the next tuesday 4:30
Assert.assertEquals( ChronoUnit.WEEKS.between(previous_monday,tuesday_4_30), 0);
// 1 day between tuesday_4_30 and tuesday_6_30
Assert.assertEquals( ChronoUnit.DAYS.between(tuesday_4_30,tuesday_6_30), 1);
// 0 day between previous_monday and tuesday_4_30
Assert.assertEquals( ChronoUnit.DAYS.between(previous_monday,tuesday_4_30), 1);
我很想在这里使用时间调整器,我很确定我可以抵消小时和分钟,以便一天从 5:30 开始,但我不知道如何修改一周的开始.
请注意,我查看了 WeekFields但我不能让它与 ChronoUnit.XXX.between()
一起工作,所以我没有走得太远。看起来我必须编写自己的编年史,这似乎太过分了。
你能帮帮我吗?
最佳答案
注意:ChronoUnit.WEEKS.between
计算两个日期之间的整周数(7 天)。在您的情况下,星期一和星期二之间只有一天,因此它将返回 0。您可能打算改为比较一年中的星期字段。
除非您想编写自己的年表(那会很痛苦),否则您可以通过以下方式“伪造”您的日历:
- 在 UTC 和 UTC+5:30 之间来回转换以表示您的截止时间/或从日期中减去 5:30
- 为周计算添加一些简单的逻辑
下面是一个基于您的代码的粗略示例,它使所有测试都通过了 - 您可能希望将逻辑提取到一个单独的类等中。这有点 hacky,但对于您的用例来说可能已经足够了。
@Test
public void test() {
LocalDateTime tuesday_4_30 = LocalDateTime.now()
.with(TemporalAdjusters.next(DayOfWeek.TUESDAY))
.withHour(4).withMinute(30);
LocalDateTime tuesday_6_30 = tuesday_4_30.withHour(6).withMinute(30);
LocalDateTime previous_monday = tuesday_4_30.minusDays(1);
// eventual adjustment using TemporalAdjusters here? like this?
// tuesday_4_30 = tuesday_4_30.with(new MyTemporalAdjuster(DayOfWeek.TUESDAY, 5, 30));
// <do the same for 6_30 and previous monday>
// or possibly change some global parameter like Chronology, Locale, or such..
assertEquals(dayOfWeek(tuesday_4_30), DayOfWeek.MONDAY);
assertEquals(dayOfWeek(tuesday_6_30), DayOfWeek.TUESDAY);
// there is 1 week between the previous monday and the next tuesday 6:30
assertEquals(weekBetween(previous_monday, tuesday_6_30), 1);
// there is 0 week between the previous monday and the next tuesday 4:30
assertEquals(weekBetween(previous_monday, tuesday_4_30), 0);
// 1 day between tuesday_4_30 and tuesday_6_30
assertEquals(weekBetween(tuesday_4_30, tuesday_6_30), 1);
// 0 day between previous_monday and tuesday_4_30
assertEquals(weekBetween(previous_monday, tuesday_4_30), 0);
}
private static DayOfWeek dayOfWeek(LocalDateTime date) {
return date.atOffset(ZoneOffset.ofHoursMinutes(5, 30)).withOffsetSameInstant(UTC).getDayOfWeek();
}
private static int weekBetween(LocalDateTime date1, LocalDateTime date2) {
OffsetDateTime date1UTC = date1.atOffset(ZoneOffset.ofHoursMinutes(5, 30)).withOffsetSameInstant(UTC);
OffsetDateTime date2UTC = date2.atOffset(ZoneOffset.ofHoursMinutes(5, 30)).withOffsetSameInstant(UTC);
int w1 = date1UTC.get(IsoFields.WEEK_OF_WEEK_BASED_YEAR);
if (dayOfWeek(date1).getValue() >= TUESDAY.getValue()) w1++;
int w2 = date2UTC.get(IsoFields.WEEK_OF_WEEK_BASED_YEAR);
if (dayOfWeek(date2).getValue() >= TUESDAY.getValue()) w2++;
return w2 - w1;
}
替代实现,可能更清洁:
private static DayOfWeek dayOfWeek(LocalDateTime date) {
return adjust(date).getDayOfWeek();
}
private static int weekBetween(LocalDateTime date1, LocalDateTime date2) {
int w1 = adjust(date1).get(IsoFields.WEEK_OF_WEEK_BASED_YEAR);
if (dayOfWeek(date1).getValue() >= TUESDAY.getValue()) w1++;
int w2 = adjust(date2).get(IsoFields.WEEK_OF_WEEK_BASED_YEAR);
if (dayOfWeek(date2).getValue() >= TUESDAY.getValue()) w2++;
return w2 - w1;
}
private static LocalDateTime adjust(LocalDateTime date) {
return date.minusHours(5).minusMinutes(30);
}
关于Java8 java.time : how to change the day of the week and the start time of the day?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37995022/