我有一个带有年周格式的字符串,例如“2015-40”和年月格式,例如“2015-08”,它想在Scala中转换为LocalDate。
我试过使用
val date = "2015-40"
val formatter = DateTimeFormatter.ofPattern("yyyy-ww")
LocalDate.parse(date, formatter)
但最终出现 DateTimeParseException 错误。将不胜感激如何做到这一点的任何帮助
提前致谢
我有一个带有年周格式的字符串,例如“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 天中的哪一天,并且拒绝为您做出选择。在我上面的代码中,我指定了星期一。一周中的任何其他日子都应该工作。DateTimeFormatter
我们想要解析(或打印)周年,我们需要使用大写YYYY
而不是小写yyyy
(或uuuu
)。顺便说一句,如果您可以影响格式,请考虑2015-W40
使用W
. 这是年和周的 ISO 8601 格式。在 ISO 中2015-12
表示年和月,许多人会这样读。所以要消除歧义,避免误读。
编辑:
在我的解释中,我假设了 ISO 周计划(星期一是一周的第一天,第 1 周被定义为新年中至少有 4 天的第一周)。您可以将不同的语言环境传递给格式化程序构建器以获得不同的周计划。
如果您确定您的周数遵循 ISO,则 Andreas 在评论中的建议已经足够好,我们希望将其作为答案的一部分:
或者,添加ThreeTen Extra库,这样您就可以使用
YearWeek
该类,它有一个很好的atDay(DayOfWeek dayOfWeek)
方法来获取LocalDate
.
链接: 维基百科文章: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