英文:
How to get the start and end of a calendar week as LocalDateTime (java 8)
问题
我想将以下字符串转换为两个日期:
起始日期可以使用以下格式化:
private final DateTimeFormatter startOfWeekFormat = new DateTimeFormatterBuilder()
.appendPattern("ww/YY")
.parseDefaulting(WeekFields.ISO.dayOfWeek(), 1)
.toFormatter();
调用该格式化后返回:26.08.2019
LocalDate.parse(cw, startOfWeekFormat).atStartOfDay();
但我在处理下一周的结束(实际上是下一周的开始)时遇到了困难,即"36/19"。
我尝试添加8天,但这会引发异常:
private final DateTimeFormatter endOfWeekFormat = new DateTimeFormatterBuilder()
.appendPattern("ww/YY")
.parseDefaulting(WeekFields.ISO.dayOfWeek(), 8)
.toFormatter();
英文:
I want to transform the following String:
private String cw = "35/19"
into 2 dates.
The start date can be formatted with:
private final DateTimeFormatter startOfWeekFormat = new DateTimeFormatterBuilder()
.appendPattern("ww/YY")
.parseDefaulting(WeekFields.ISO.dayOfWeek(), 1)
.toFormatter();
which when called returns: 26.08.2019
LocalDate.parse(cw, startOfWeekFormat).atStartOfDay();
But I struggle with the end of the week which is basically the start of the next week "36/19".
I tried to add plus 8 days, but that throws an exception:
private final DateTimeFormatter endOfWeekFormat = new DateTimeFormatterBuilder()
.appendPattern("ww/YY")
.parseDefaulting(WeekFields.ISO.dayOfWeek(), 8)
.toFormatter();
答案1
得分: 6
import java.time.DayOfWeek;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.time.format.DateTimeFormatterBuilder;
import java.time.temporal.TemporalAdjusters;
import java.time.temporal.WeekFields;
public class Main {
public static void main(String[] args) {
String cw = "35/19";
final DateTimeFormatter startOfWeekFormat = new DateTimeFormatterBuilder()
.appendPattern("ww/YY")
.parseDefaulting(WeekFields.ISO.dayOfWeek(), 1)
.toFormatter();
LocalDateTime ldt=LocalDate.parse(cw, startOfWeekFormat)
.atStartOfDay()
.with(TemporalAdjusters.next(DayOfWeek.MONDAY));
System.out.println(ldt);
}
}
Output:
2019-09-02T00:00
<details>
<summary>英文:</summary>
LocalDateTime ldt=LocalDate.parse(cw, startOfWeekFormat)
.atStartOfDay()
.with(TemporalAdjusters.next(DayOfWeek.MONDAY));
**Demo:**
import java.time.DayOfWeek;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.time.format.DateTimeFormatterBuilder;
import java.time.temporal.TemporalAdjusters;
import java.time.temporal.WeekFields;
public class Main {
public static void main(String[] args) {
String cw = "35/19";
final DateTimeFormatter startOfWeekFormat = new DateTimeFormatterBuilder()
.appendPattern("ww/YY")
.parseDefaulting(WeekFields.ISO.dayOfWeek(), 1)
.toFormatter();
LocalDateTime ldt=LocalDate.parse(cw, startOfWeekFormat)
.atStartOfDay()
.with(TemporalAdjusters.next(DayOfWeek.MONDAY));
System.out.println(ldt);
}
}
**Output:**
2019-09-02T00:00
</details>
# 答案2
**得分**: 1
另一个答案是以不同的方式添加一周:
我假设您总是希望得到一个日历周的开始日期和结束日期。您可以编写一个方法,返回一个`Map.Entry<LocalDate, LocalDate>`,其中键是开始日期,值是结束日期。
代码如下:
```Java
public static Map.Entry<LocalDate, LocalDate> getStartAndEndOfCalendarWeek(String calendarWeek) {
DateTimeFormatter startOfWeekFormatter = new DateTimeFormatterBuilder()
.appendPattern("ww/YY")
.parseDefaulting(WeekFields.ISO.dayOfWeek(), 1)
.toFormatter();
LocalDate weekStart = LocalDate.parse(calendarWeek, startOfWeekFormatter);
LocalDate weekEnd = weekStart.plusWeeks(1);
return new AbstractMap.SimpleEntry<LocalDate, LocalDate>(weekStart, weekEnd);
}
在main
方法中使用示例String
打印结果,代码如下:
public static void main(String[] args) {
String cw = "35/19";
Map.Entry<LocalDate, LocalDate> calendarWeekStartAndEndDate
= getStartAndEndOfCalendarWeek(cw);
System.out.println(calendarWeekStartAndEndDate.getKey()
+ " - " + calendarWeekStartAndEndDate.getValue());
}
输出将会是:
2019-08-26 - 2019-09-02
我知道这样会将结果增加一周,但我认为涉及两个不同的解析器或解析操作不会比增加一周带来任何好处。
如果您想要连续两个日历周的开始日期,那么添加一个额外的天数,代码如下:
LocalDate weekEnd = weekStart.plusWeeks(1).plusDays(1);
如果您想要一个LocalDateTime
(我不太确定您是否真的需要),您当然可以调整返回类型,并在解析weekStart
时使用.atStartOfDay()
,添加操作保持不变。
英文:
Another answer that adds a week, but in a different way:
I assume you always want the start date and the end date of a calendar week. You could write a method that returns a Map.Entry<LocalDate, LocalDate>
where the key is the start date and the value is the end date.
It could look like this:
public static Map.Entry<LocalDate, LocalDate> getStartAndEndOfCalendarWeek(String calendarWeek) {
DateTimeFormatter startOfWeekFormatter = new DateTimeFormatterBuilder()
.appendPattern("ww/YY")
.parseDefaulting(WeekFields.ISO.dayOfWeek(), 1)
.toFormatter();
LocalDate weekStart = LocalDate.parse(calendarWeek, startOfWeekFormatter);
LocalDate weekEnd = weekStart.plusWeeks(1);
return new AbstractMap.SimpleEntry<LocalDate, LocalDate>(weekStart, weekEnd);
}
Printing the result in a main
with your example String
like this
public static void main(String[] args) {
String cw = "35/19";
Map.Entry<LocalDate, LocalDate> calendarWeekStartAndEndDate
= getStartAndEndOfCalendarWeek(cw);
System.out.println(calendarWeekStartAndEndDate.getKey()
+ " - " + calendarWeekStartAndEndDate.getValue());
}
would output
2019-08-26 - 2019-09-02
I know this adds a week to the result of using your DateTimeFormatter
to parse the String
, but I don't think involving two different parsers or parsing actions would cause any benefit over adding a week.
If you want the starts of two consecutive calendar weeks, the make the addition add an additional day, like this:
LocalDate weekEnd = weekStart.plusWeeks(1).plusDays(1);
and if you want a LocalDateTime
(which is not quite clear to me if you really do), you could of course adjust the return type and use .atStartOfDay()
when you parse the weekStart
, the addition would stay the same.
答案3
得分: 1
> 我更希望有一种解决方案,不需要将额外的天数添加到解析后的结果中。
> 就像一种解决方案,其中“plus(8)”已经包含在格式化程序中。
这是不可能的。你不能将 2020-08-30
解析为 2020-08-31 或者 2020-09-30。同样地,你也不能将 35/19
解析为2019年第36周的日期。
我非常赞成半开区间,因此我理解在你的情况下这会很实用。很抱歉这是不可能的。
链接:半开区间 在WolframMathWorld。
英文:
> I'd prefer an solution where I don't need to add the additional days
> to the result of the parsed string. Like a solution where the
> "plus(8)" is already included in the formatter.
That is not possible. You can’t parse 2020-08-30
into 2020-08-31 or 2020-09-30. Just as well you cannot parse 35/19
into a date in week 36 of 2019.
I’m all in favour of half-open intervals, so I do see that it would be practical in your situation. Sorry that it isn’t possible.
Link: Half-Open Interval in WolframMathWorld.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论