如何将一年中的几周转换为localdate

ua4mk5z4  于 2021-07-08  发布在  Java
关注(0)|答案(2)|浏览(782)

我有一个字符串,包含年周格式(例如“2015-40”)和年月格式(例如“2015-08”),希望在scala中转换为localdate。
我试过使用

val date = "2015-40"
val formatter = DateTimeFormatter.ofPattern("yyyy-ww") 
LocalDate.parse(date, formatter)

但最终会出现datetimeparseexception错误。如果您能帮上忙,我将不胜感激
提前谢谢

umuewwlo

umuewwlo1#

LocalDate 有三个部分:年,月和月日。所以,在 year-month 弦,你得去拿 LocalDate 根据您的要求在特定的一天。解析year-month字符串非常简单,如演示代码所示。
如果是 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
oyjwcjzk

oyjwcjzk2#

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不知道你想要哪一天,拒绝为你做选择。在我上面的代码中,我指定了星期一。一周中的其他任何一天都应该工作。
有点微妙。虽然对人类来说,2015年和第40周是明确的,但新年前后的情况并不总是一样,第一周可能在新年前开始,第52周或第53周则在新年后延长。所以日历年和周数并不总是定义一个特定的周。相反,我们需要一个周-年或基于周的年的概念。一年中的一周从第一周(含第一周)开始,不管这意味着它是在新年前几天还是新年后几天开始。它一直持续到最后一周的最后一天,通常是在新年前后的几天。告诉某人 DateTimeFormatter 我们想要解析(或打印)我们需要使用大写的周-年 YYYY 而不是小写 yyyy (或 uuuu ).
另外,如果你能影响格式,考虑 2015-W40 用一个 W . 这是iso 8601年和周的格式。在iso中 2015-12 表示年和月,很多人会这样读。所以要消除歧义,避免误读。
编辑:
在我的解释中,我假设iso周计划(星期一是一周的第一天,第1周定义为新年中至少有4天的第一周)。您可以将不同的区域设置传递给格式化程序生成器以获得不同的周方案。
如果您确信您的周数遵循iso,andreas在评论中的建议足够好,我们希望作为答案的一部分:
或者,添加三个额外的库,这样您就可以使用 YearWeek 同学们,这是一个美好的时刻 atDay​(DayOfWeek dayOfWeek) 获取数据的方法 LocalDate .
link:wikipedia article:iso 8601标准

相关问题