Instant time from week of year

Kirill :

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)?

Ole V.V. :
    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.

Guess you like

Origin http://10.200.1.11:23101/article/api/json?id=415116&siteId=1