I need to get Instant
time from week number of year. Now I'm using old Calendar
API to calculate time:
int week = 1; // week of year
final Calendar cal = new GregorianCalendar();
cal.set(0, 1, 0, 0, 0, 0); // reset calendar
cal.set(Calendar.YEAR, Year.now().getValue());
cal.set(Calendar.WEEK_OF_YEAR, week);
cal.setTimeZone(TimeZone.getTimeZone(ZoneOffset.UTC));
final Instant start = cal.getTime().toInstant();
final Instant end = start.plus(Period.ofWeeks(1));
Is it possible to get Instant
from week of year using new Java time API (java.time
package)?
WeekFields wf = WeekFields.of(Locale.getDefault());
int week = 1; // week of year
LocalDate startDate = LocalDate.now(ZoneOffset.UTC)
.with(wf.weekOfWeekBasedYear(), week)
.with(wf.dayOfWeek(), 1);
Instant startInstant = startDate.atStartOfDay(ZoneOffset.UTC).toInstant();
LocalDate endDate = startDate.plusWeeks(1);
Instant endInstant = endDate.atStartOfDay(ZoneOffset.UTC).toInstant();
System.out.println("" + startInstant + " - " + endInstant);
My locale uses ISO week numbers. The output here was:
2019-12-29T00:00:00Z - 2020-01-05T00:00:00Z
If you want ISO weeks independently of the locale, set wf
to WeekFields.ISO
. If you want some other week numbering scheme, set wf
accordingly.
In case any other readers were wondering, Kirill is defining the end of the week as the first moment of the following week. This is recommended. It’s known as using half-open intervals for time intervals.
I also agree with the question that one should clearly prefer using java.time for this task rather than Calendar
. Calendar
is poorly designed and long outdated, and I believe that the code using java.time is clearer to read.
Furthermore, the code in the question using Calendar
doesn’t set the day to the first day of the week, so will not give you that day. And while I haven’t tested, I suspect that the code will sometimes produce unexpected results around New Year.
My code using WeekFields
from java.time will stay within the current week-based year, which is not the same as the calendar year. For example, if I had run it on December 30, 2019, it would still have given med week 1 of 2020 because we were already in that week.