当前位置: 首页 > 知识库问答 >
问题:

如何确定通过java中的周数和天数(周)的日期

阎辰钊
2023-03-14

我需要通过传递这些参数来获取日期

  1. 年份

我在Calendar类中查找构造函数,但不包含这些参数。

共有3个答案

卢知
2023-03-14

正如@Ole V.V.所解释的,您需要定义一周从哪一天开始,以及第一周必须考虑的天数。

例如,ISO-8601标准考虑:

  • 周一是一周的第一天

该月分为多个时段,每个时段从一周中定义的第一天开始。如果当月最早的时间段少于最小天数,则称为周0,如果至少有最小天数,则称为周1

根据你如何定义它们,你可以得到不同的结果。考虑2017年7月的日历:

     July 2017
Su Mo Tu We Th Fr Sa
                   1
 2  3  4  5  6  7  8
 9 10 11 12 13 14 15
16 17 18 19 20 21 22
23 24 25 26 27 28 29
30 31

如果我们考虑ISO的定义,我们有:

  • 第0周- 2017-07-01到2017-07-02
  • 第一周:从2017-07-03到2017-07-09
  • 第2周:从2017-07-10到2017-07-16
  • 第3周:从2017-07-17到2017-07-22
  • 第4周:从2017-07-23到2017-07-30
  • 周5: 2017-07-31

如果我们将一周的第一天视为周日,将第一周的最小天数视为1,则我们有:

  • 第一周:2017-07-01

由于日历的解决方案已经发布,我将使用新的API编写一个解决方案。如果您使用的是Java8,请考虑使用新的Java。时间API。与旧的API相比,它更容易实现,更少出现错误,更不容易出错。

如果你用Java

下面的代码适用于这两种情况。唯一的区别是包名(在Java8中是Java.time),而在ThreeTen Backport(或Android的ThreeTenABP)中是org。三十。bp),但类和方法名称相同。

我使用的是DateTimeFormatter,因为它包含所有字段(月、年、周和月的周),并相应地解析日期,创建一个LocalDate(其中包含日/月/年字段)。我还使用了WeekFields类,它可以配置为使用不同的周定义(第一周的第一天和最小天数)

还有一点调整,将周日视为零:

public LocalDate getDate(int weekOfMonth, int dayOfWeek, int month, int year) {
    // you can customize your week definition (first day of week and mininum days in first week)
    WeekFields wf = WeekFields.of(DayOfWeek.SUNDAY, 2);
    DateTimeFormatter fmt = new DateTimeFormatterBuilder()
        // week of month, using week definition from WeekFields
        .appendValue(wf.weekOfMonth()).appendPattern(" ")
        // day of week
        .appendValue(ChronoField.DAY_OF_WEEK)
        // month and year
        .appendPattern(" M/yyyy")
        // create formatter
        .toFormatter();

    return LocalDate.parse(weekOfMonth + " " +
           // Sunday is 0, adjusting value
           (dayOfWeek == 0 ? 7 : dayOfWeek) + " " + month + "/" + year, fmt);
}

使用此代码(一周从周日开始,需要将2天视为第一周,否则,如上面第一个示例所示,一周将为零):

LocalDate d = getDate(1, 6, 7, 2017);

d将于2017年7月8日(2017年7月1日星期六)举行。

如果要使用ISO 8601定义,请使用常量WeekFields. ISO而不是使用WeekFields.of()方法。

正如@Ole V.V.在评论中所建议的,也可以在不创建格式化程序的情况下完成:获取当月的第一个dayOfWeek,并将其调整到所需的weekOfMonth

public LocalDate getDate(int weekOfMonth, int dayOfWeek, int month, int year) {
    // you can customize your week definition (first day of week and mininum days in first week)
    WeekFields wf = WeekFields.of(DayOfWeek.SUNDAY, 2);

    // Sunday is 0, adjusting value
    DayOfWeek dow = DayOfWeek.of(dayOfWeek == 0 ? 7 : dayOfWeek);

    // get the first weekday of the month
    LocalDate first = LocalDate.of(year, month, 1).with(TemporalAdjusters.nextOrSame(dow));

    // check in which week this date is
    int week = first.get(wf.weekOfMonth());

    // adjust to weekOfMonth
    return first.plusWeeks(weekOfMonth - week);
}

这种方法的工作原理完全相同,但不需要格式化程序——我用1600年到2100年的数据进行了测试,得到了相同的结果。

PS:Calendar也通过方法setFirstDayOfWeek()setMinimalDaysInFirstWeek()具有类似的配置。您可以通过调用相应的get方法来检查默认配置。

时宾实
2023-03-14

要从年份、周数和星期几创建日期,请使用java.util.Calendar实例:

Calendar cal = Calendar.getInstance();
        cal.set(Calendar.YEAR, 2017);
        cal.set(Calendar.WEEK_OF_YEAR, 26);
        cal.set(Calendar.DAY_OF_WEEK, Calendar.MONDAY);

日历转换为java。util。日期

Date date = cal.getTime();

Date转换为java。时间LocalDateTime使用:

LocalDateTime localDateTime = LocalDateTime.ofInstant(date.toInstant(), ZoneId.systemDefault());
潘星阑
2023-03-14

尽管你有标签,我同意Joe C的评论,但你应该更喜欢现代Java日期和时间API(又名java.time或JSR-310),而不是早已过时的Calendar和朋友。现代类对程序员更友好,使用起来更友好,它们带来的惊喜更少,导致更清晰、更自然的代码(至少在你习惯流畅的风格时),并且在你犯错误时更容易调试。

我不知道你是如何计算每个月的周数的,我假设第一周从月初开始,持续7天(所以第二周从8号开始,第5周从29号开始),如果你的计算方式不同,请看雨果的回答。

我建议这种方法:

public static LocalDate weekNoAndDayToDate(Year year, Month month, int weekOfMonth, int dayOfWeek) {
    // find day of week: convert from 0 (Sunday) to 6 (Saturday)
    // to DayOfWeek, from 1 (Monday) to 7 (Sunday)
    DayOfWeek dow;
    if (dayOfWeek == 0) { // Sunday
        dow = DayOfWeek.SUNDAY;
    } else {
        dow = DayOfWeek.of(dayOfWeek);
    }
    return year.atMonth(month)
            .atDay(1)
            .with(TemporalAdjusters.nextOrSame(dow))
            .with(ChronoField.ALIGNED_WEEK_OF_MONTH, weekOfMonth);
}

例如,我们可以这样做

    LocalDate today = weekNoAndDayToDate(Year.of(2017), Month.JULY, 1, 1);

这就产生了

2017-07-03

如果您需要DateGregorianCalendar,例如对于您无法更改的旧API,请执行以下操作之一:

    Date oldfashiondDateObject
            = Date.from(today.atStartOfDay(ZoneId.systemDefault()).toInstant());
    GregorianCalendar oldfashionedCalendarObject
            = GregorianCalendar.from(today.atStartOfDay(ZoneId.systemDefault()));

在这两种情况下,结果在不同的时区会有所不同(这是旧课程固有的问题之一)。在我的电脑上,第一个生成日期

Mon Jul 03 00:00:00 CEST 2017

第二个生成一个gregorianalendar等于同一时间点。

 类似资料:
  • 如何通过给出一个月中的一周和一周中的一天来获得日期。 示例:如果我需要2018年11月的第三个星期二。 月周:3,周日:3 预计日期:2018年11月20日 但我们得到的价值是:2018年11月13日。因为本月的开始日(星期四)少于预期的日期(星期二)。 我怎样才能得到正确的日期??

  • 在我的android应用程序中,我正在努力获取提供日期的周数。但是它没有给我正确的周数,我正在使用下面的代码来获取周数。 从上述日历中可以看出,截至2016年1月,属于第1周的天数只有第1、第2和第3天。第二周的相关天数为第四、第五、第六、第七、第八、第九和第十天。第三周的相关天数为11、12、13、14、15、16和17日,依此类推。但对于2016年1月12日,上述代码给出了第2周,而不是第3周

  • 问题内容: 我想查找给定月份中的所有星期六和星期日。我该怎么办? 问题答案: 在 最简单 的方法是只迭代所有在一个月的日子里,检查一周的某一天为他们每个人。例如: 我 绝对可以确定 ,这样做的方式要高效得多-但这就是我的出发点,当发现速度太慢时进行优化。 请注意,如果您能够使用Joda Time,那将使您的生活更加轻松…

  • 如何分类?例如,我希望一周的第一天是星期一。由此: 周一至周二周三至周五周六 我想要这个: 星期一至星期二星期三星期五星期六至星期日 或者我希望我一周的第一天是周五 那么在输出中应该是这样的: 星期五星期六星期一星期二星期三星期四

  • 我正在尝试为我们的财务部门生成一些代码,他们需要一个字段,该字段将为他们提供一年中的当前一周,但以星期天为基础,这是一周的第一天。例如01-25-16(MM dd yyyy)将是第4周。然而,当我尝试使用和

  • 问题内容: 我目前正在使用vbscript函数以2/12/2009格式获取本周和上周的第一天值。我想知道是否可以使用SQL查询。 问题答案: 这些语句应该在TSQL中完成您想要的操作。请注意,这些报表基于当前日期。您可以将getdate()替换为所需的任何日期: