bashoogzaad
bashoogzaad

Reputation: 4781

Get LocalDateTime based on year and week of year

I have two integers: year and week. I would like to construct a LocalDateTime from these two values, where the date represents the first day of the particular week in the particular year.

I already tried this:

LocalDateTime ldt = LocalDateTime.of(year, 1, 1, 0, 0).plusWeeks(week-1);

This does not give the correct result, because the first day of the year is not always the beginning of the first week of that year. I can not seem to figure out how to get the first day of the first week either.

Is there any simple way to do this with the Date and Time API in Java 8?

Note: I know I could also create a workaround with answers given here, but this seems to far-fetched. Maybe it isn't, if so, let me know!

Upvotes: 11

Views: 11952

Answers (4)

Vovka
Vovka

Reputation: 599

LocalDate ld = LocalDate.parse("2012-W48-1", DateTimeFormatter.ISO_WEEK_DATE);

Upvotes: 4

Basil Bourque
Basil Bourque

Reputation: 340118

ThreeTen-Extra

The ThreeTen-Extra project extends java.time with additional classes. This project is a proving ground for possible future additions to java.time. You may find some useful classes here such as YearWeek.

If by “week” you meant the standard ISO 8601 definition of a week-of-year where the week # 1 contains the first Thursday of the year, let the YearWeek class do the work for you.

int weekBasedYear = 2015;  // Not the calendar year!
int weekOfYear = 1;
YearWeek yearWeek = YearWeek.of ( weekBasedYear , weekOfYear );

You can get a date-only value represented in a LocalDate object. Specify which day-of-week you want using the DayOfWeek enum, where Monday is the first day of the week, and Sunday is last day. Remember that an ISO week always starts on a Monday and always ends on a Sunday.

LocalDate mondayOfYearWeek = yearWeek.atDay ( DayOfWeek.MONDAY );
LocalDate sundayOfYearWeek = yearWeek.atDay ( DayOfWeek.SUNDAY );

Dump to console. Note how the week starts in previous calendar year (2014) and ends in 2015, because January 1, 2015 is a Thursday so it marks ISO Week # 1. The following Sunday, January 4, 2015 concludes ISO Week # 1.

System.out.println ( "yearWeek: " + yearWeek + " starts on mondayOfYearWeek: " + mondayOfYearWeek + " and ends on sundayOfYearWeek: " + sundayOfYearWeek );

yearWeek: 2015-W01 starts on mondayOfYearWeek: 2014-12-29 and ends on sundayOfYearWeek: 2015-01-04

Upvotes: 3

Tunaki
Tunaki

Reputation: 137289

The following code will get a LocalDateTime and set it to the first day of the given week-of-year for the given year:

int week = 1;
int year = 2016;
WeekFields weekFields = WeekFields.of(Locale.getDefault());
LocalDateTime ldt = LocalDateTime.now()
                            .withYear(year)
                            .with(weekFields.weekOfYear(), week)
                            .with(weekFields.dayOfWeek(), 1);
System.out.println(ldt);

Note that the notion of week-of-year is locale specific. Here, I used the default Locale but you might need to use a user-provided locale.

If you want to get rid of the time part, you can add a call to truncatedTo(ChronoUnit.DAYS).

Upvotes: 19

assylias
assylias

Reputation: 328873

You could try to parse a string representation of the day you are interested in:

private static final DateTimeFormatter YEAR_WEEK = DateTimeFormatter.ofPattern("YYYY-w-e", Locale.getDefault());

public static LocalDate fromYearWeek(int year, int week) {
  return LocalDate.parse(year + "-" + week + "-1", YEAR_WEEK);
}

If you need a LocalDateTime, you can then use localDate.atTime(...) or localDate.atStartOfDay() for example.

Upvotes: 2

Related Questions