Matthew Layton
Matthew Layton

Reputation: 42229

Java 8 Date API - Get total number of weeks in a month

I have a Kotlin function to get the total number of weeks in a month

Code

fun getTotalWeeksInMonth(instant: Instant): Int {
    val calendar = Calendar.getInstance()
    calendar.time = Date.from(instant)

    return calendar.getActualMaximum(Calendar.WEEK_OF_MONTH)
}

However this is using a mix of the old Java date/time APIs (Date and Calendar) and the new APIs (Instant)

How would I achieve the same result, using just the new APIs?

Upvotes: 4

Views: 2336

Answers (4)

ETO
ETO

Reputation: 7269

Having an Instant I would convert it to date first:

val date = LocalDateTime.ofInstant(instant, ZoneId.systemDefault())

Then go with either

YearMonth.from(date).atEndOfMonth().get(ChronoField.ALIGNED_WEEK_OF_MONTH)

or

YearMonth.from(date).atEndOfMonth().get(WeekFields.ISO.weekOfMonth())

Complete example:

fun getTotalWeeksInMonth(instant: Instant): Int {
    val date = LocalDateTime.ofInstant(instant, ZoneId.systemDefault())
    return YearMonth.from(date).atEndOfMonth().get(ChronoField.ALIGNED_WEEK_OF_MONTH)
}

Upvotes: 0

Schidu Luca
Schidu Luca

Reputation: 3947

You can try something like this pair of lines:

YearMonth currentYearMonth = 
    YearMonth.now( 
        ZoneId.systemDefault() 
    )
;
int weeks = 
    currentYearMonth
    .atEndOfMonth()
    .get(
        WeekFields.ISO.weekOfMonth()
    )
;

Upvotes: 4

xingbin
xingbin

Reputation: 28269

You can evaluate the "week of month" of last day of this month, in java:

static int getTotalWeeksInMonth(Instant instant) {
    LocalDate localDate = LocalDate.ofInstant(instant, ZoneId.systemDefault());
    LocalDate lastDayOfMonth = localDate.withDayOfMonth(localDate.lengthOfMonth());
    int lastWeekOfMonth = lastDayOfMonth.get(WeekFields.ISO.weekOfMonth());
    return lastWeekOfMonth;
}

Upvotes: 1

Shadov
Shadov

Reputation: 5592

See if this fits you, be careful about what Zone you are actually passing, and about WeekFields.ISO, in some regions it may work fine, but in others it may not:

Instant now = Instant.now();

ZonedDateTime zonedNow = now.atZone(ZoneId.systemDefault());
ZonedDateTime monthEnd = zonedNow.with(TemporalAdjusters.lastDayOfMonth());

System.out.println(monthEnd.get(WeekFields.ISO.weekOfMonth()));

Upvotes: 0

Related Questions