我有一个包含年份周的字符串,例如"2015-40";以及年月格式,例如";2015-08";,希望在Scala中转换为LocalDate。
我试过使用
val date = "2015-40"
val formatter = DateTimeFormatter.ofPattern("yyyy-ww")
LocalDate.parse(date, formatter)
但最终出现DateTimeParseException错误。如果有任何关于如何进行的帮助,我将不胜感激
提前感谢
String date = "2015-40";
DateTimeFormatter formatter = new DateTimeFormatterBuilder()
.appendPattern("YYYY-ww")
.parseDefaulting(ChronoField.DAY_OF_WEEK, DayOfWeek.MONDAY.getValue())
.toFormatter(Locale.FRANCE);
LocalDate ld = LocalDate.parse(date, formatter);
System.out.println(ld);
很抱歉,我只能写Java,我相信你能翻译成Scala。输出为:
2015-09-28
为什么会出现异常?我们缺少一些东西来将2015-40
解析为LocalDate
:
LocalDate
是一个日历日期,第40周由7天组成。Java不知道你想要这7天中的哪一天,也拒绝为你做出选择。在我上面的代码中,我指定了星期一。一周中的任何一天都应该工作- 有点微妙。虽然对人类来说,2015年和第40周是明确的,但新年前后的情况并不总是如此,第一周可能在新年前开始,第52或53周可能在元旦后延长。因此,日历年和周数并不总是定义一个特定的周。相反,我们需要周-年或基于周的年
顺便说一句,如果可以影响格式,可以考虑2015-W40
和W
。这是适用于年和周的ISO 8601格式。在ISO中,2015-12
表示年份和月份,许多人会这样读。因此,要消除歧义,避免误读。
编辑:
在我的解释中,我假设ISO周计划(周一是一周的第一天,第1周被定义为新年中至少有4天的第一周(。您可以将不同的区域设置传递给格式化程序生成器,以获得不同的周方案。
如果你确信你的几周遵循ISO,Andreas在评论中的建议足够好,我们希望作为答案的一部分:
或者,添加ThreeTen Extra库,这样您就可以使用
YearWeek
阶级,有一个很好的atDay(DayOfWeek dayOfWeek)
获得CCD_ 13。
链接:维基百科文章:ISO 8601
LocalDate
有三个部分:年、月和月中日。因此,在year-month
字符串的情况下,您必须根据您的要求在特定的一天获得LocalDate
。分析年-月字符串是直接的,如演示代码所示。
在year-week
字符串的情况下,您必须在一周中的特定日期获取LocalDate
,例如周一或今天等。此外,我发现与其直接解析字符串,不如获取年份和周,然后使用方法LocalDate
来获取所需的LocalDate
实例。
import java.time.DayOfWeek;
import java.time.LocalDate;
import java.time.YearMonth;
import java.time.format.DateTimeFormatter;
import java.time.temporal.TemporalAdjusters;
import java.time.temporal.WeekFields;
public class Main {
public static void main(String[] args) {
//#################### Year-Month #######################
// Given year-month string
var yearMonthStr = "2015-08";
// LocalDate parsed from yearMonthStr and on the 1st day of the month
LocalDate date2 = YearMonth.parse(yearMonthStr, DateTimeFormatter.ofPattern("u-M")).atDay(1);
System.out.println(date2);
// LocalDate parsed from yearMonthStr and on the last day of the month
date2 = YearMonth.parse(yearMonthStr, DateTimeFormatter.ofPattern("u-M")).atEndOfMonth();
System.out.println(date2);
// LocalDate parsed from yearMonthStr and on specific day of the month
date2 = YearMonth.parse(yearMonthStr, DateTimeFormatter.ofPattern("u-M")).atDay(1).withDayOfMonth(10);
System.out.println(date2);
//#################### Year-Week #######################
// Given year-week string
var yearWeekStr = "2015-40";
// Split the string on '-' and get year and week values
String[] parts = yearWeekStr.split("-");
int year = Integer.parseInt(parts[0]);
int week = Integer.parseInt(parts[1]);
// LocalDate with year, week and today's day e.g. Fri
LocalDate date1 = LocalDate.now()
.withYear(year)
.with(WeekFields.ISO.weekOfYear(), week);
System.out.println(date1);
// LocalDate with year, week and next Mon (or same if today is Mon)
date1 = LocalDate.now()
.withYear(year)
.with(WeekFields.ISO.weekOfYear(), week)
.with(TemporalAdjusters.nextOrSame(DayOfWeek.MONDAY));
System.out.println(date1);
// LocalDate with year, week and today's day previous Mon (or same if today is Mon)
date1 = LocalDate.now()
.withYear(year)
.with(WeekFields.ISO.weekOfYear(), week)
.with(TemporalAdjusters.previousOrSame(DayOfWeek.MONDAY));
System.out.println(date1);
}
}
输出:
2015-08-01
2015-08-31
2015-08-10
2015-10-02
2015-10-05
2015-09-28