问题
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?
回答1:
You can try something like this pair of lines:
YearMonth currentYearMonth =
YearMonth.now(
ZoneId.systemDefault()
)
;
int weeks =
currentYearMonth
.atEndOfMonth()
.get(
WeekFields.ISO.weekOfMonth()
)
;
回答2:
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;
}
回答3:
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()));
回答4:
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)
}
来源:https://stackoverflow.com/questions/54041780/java-8-date-api-get-total-number-of-weeks-in-a-month