Rectangle 27 0

How to determine the date passing the Week Number and Day Number (Week) in java?


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
Calendar
LocalDate d = getDate(1, 6, 7, 2017);
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);
}
  • The minimal number of days in the first week: the standard counts the first week as needing at least 4 days

@OleV.V. Done! Indeed, it's much better than using a formatter, thanks a lot!

@OleV.V. I haven't tried without a formatter yet. Let's see if it works, I'll update the answer if I find a way. Thanks! - I used a formatter because it already resolves the day based on the other fields, but let's see if it can be done in another way...

Ah, the WeekFields class, of course. Thanks. Couldnt it be done without building a string and parsing it? I think I would try getting the week number of the first Thursday of the month (for example; which day-of-week was required) using WeekFields.weekOfMonth(). Then add the appropriate number of weeks using LocalDate.plusWeeks().

As @Ole V.V. explained, you need to define in what day the week starts, and how many days it must have to be considered the first week.

As @Ole V.V. suggested in the comments, it can also be done without creating a formatter: get the first dayOfWeek of the month and adjust it to the desired weekOfMonth:

Depending on how you define those, you can have different results. Consider the calendar for July 2017:

I am very fond of the cooperation you and I are having, Hugo. Two minds think better than one.

I'm using a DateTimeFormatter because it takes all the fields (month, year, day of week and week of month) and resolves the day accordingly, creating a LocalDate (which has the day/month/year fields). I'm also using the WeekFields class, which can be configured to use different week definitions (first day and minimal number of days in first week)

If we consider first day of week as Sunday and minimal number of days in the first week as 1, we have:

If you want to use ISO 8601 definition, use the constant WeekFields.ISO instead of using WeekFields.of() method.

If you're using Java <= 7, you can use the ThreeTen Backport, a great backport for Java 8's new date/time classes. And for Android, there's the ThreeTenABP (more on how to use it here).

PS: Calendar also has a similar configuration via the methods setFirstDayOfWeek() and setMinimalDaysInFirstWeek(). You can check the default configuration calling the respective get methods.

The code below works for both. The only difference is the package names (in Java 8 is java.time and in ThreeTen Backport (or Android's ThreeTenABP) is org.threeten.bp), but the classes and methods names are the same.

The month is divided into periods where each period starts on the defined first day-of-week. The earliest period in the same month is referred to as week 0 if it has less than the minimal number of days and week 1 if it has at least the minimal number of days.

There's also a little adjustment to consider Sunday as zero:

This works exactly the same way, but without the need of a formatter - I've tested with dates from year 1600 to 2100 and it gets the same results.

Using this code (week starts on Sunday, and 2 days are required to be considered the first week - otherwise week will be zero as in the first example above):

d will be 2017-07-08 (Saturday in the week 1 of July 2017).

Note
Rectangle 27 0

How to determine the date passing the Week Number and Day Number (Week) in java?


Date oldfashiondDateObject
            = Date.from(today.atStartOfDay(ZoneId.systemDefault()).toInstant());
    GregorianCalendar oldfashionedCalendarObject
            = GregorianCalendar.from(today.atStartOfDay(ZoneId.systemDefault()));
LocalDate today = weekNoAndDayToDate(Year.of(2017), Month.JULY, 1, 1);
2017-07-03
Mon Jul 03 00:00:00 CEST 2017
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);
}

I dont know how you count your weeks of the month. I have assumed that the first week starts on the first of the month and lasts 7 days (so the second week starts on the 8th and the 5th week on the 29th day of the month). If you count differently, please see Hugos answer.

If you need either a Date or a GregorianCalendar, for example for an old API that you cannot change, do one of the following:

In both cases the result will be different in different time zones (one of the inherent troubles of the old classes). On my computer the first yields a Date of

In spite of your tags I agree with Joe Cs comment, you should prefer the modern Java date and time API (AKA known as java.time or JSR-310) over the long outdated Calendar and friends. The modern classes are more programmer friendly and nicer to work with, they come with fewer surprises, lead to clearer and more natural code (at least when you get used to the fluent style) and are easier to debug should you make a bug.

The second yields a GregorianCalendar equal to the same point in time.

Note
Rectangle 27 0

How to determine the date passing the Week Number and Day Number (Week) in java?


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);
Date
Date date = cal.getTime();
LocalDateTime localDateTime = LocalDateTime.ofInstant(date.toInstant(), ZoneId.systemDefault());
java.time.LocalDateTime
java.util.Date

I had the same problem that @Newb, and this example not resolve this big problem!

I replaced WEEK OF YEAR with WEEK OF MONTH AND MONTH and it was ok. Same results. Thanks!

If converting into java.time, use Instant and ZonedDateTime rather than LocalDateTime. No point in purposely discarding timezone/offset information. Also, you should avoid the troublesome old legacy date-time classes as java.time was added to supplant them entirely. In this year of 2017, the other Answers by Ole V.V. or Hugo should have been accepted rather than this one.

To create date from year, week number and week's day use java.util.Calendar instance:

Note