Using the NodaTime library, how can I calculate a LocalDate of the first day of the week based on a Week number and week WeekYear.
The reverse of this:
var date = new LocalDate(2012, 1, 1);
int weekYear = date.WeekYear; // 2011
int weekNr = date.WeekOfWeekYear; // 52
Something like this fake code:
var newDate = LocalDate.FirstDayFromWeek(weekYear, weekNr);
Firstly, you should be looking at how to construct the relevant LocalDate
- that's all the information you logically have if you've got a WeekYear
and WeekOfWeekYear
. You can then get a LocalDateTime
from a LocalDate
with AtMidnight
if you really want - but I'd stick with LocalDate
until you really need anything else, as that way you're synthesizing less information.
I don't believe we currently make this particularly simple, to be honest - although the underlying engine supports enough computations that we could add it fairly easily.
Without any changes to the API, I would suggest you'd probably be best off with something like:
- Construct June 1st within the desired year, which should have the same
WeekYear
(I'm assuming you're using the ISO calendar...)
- Get to the first day of the week (
date = date.Previous(IsoDayOfWeek.Monday)
)
- Work out the current week number
- Add or subtract the right number of weeks
So something like:
public static LocalDate LocalDateFromWeekYearAndWeek(int weekYear,
int weekOfWeekYear)
{
LocalDate midYear = new LocalDate(weekYear, 6, 1);
LocalDate startOfWeek = midYear.Previous(IsoDayOfWeek.Monday);
return startOfWeek.PlusWeeks(weekOfWeekYear - startOfWeek.WeekOfWeekYear);
}
Not terribly pleasant or efficient, but not too bad... if you find yourself wanting to do a lot of work with WeekOfWeekYear
and WeekYear
, please raise feature requests for the kind of thing you want to do.
EDIT: Just as an update, we now support this:
LocalDate date = LocalDate.FromWeekYearWeekAndDay(year, week, IsoDayOfWeek.Monday);
The code below returns 2018-11-04 as being the first day of week 44:
LocalDate.FromWeekYearWeekAndDay(2018, 44, IsoDayOfWeek.Sunday);
But the dates 2018-10-28, 2018-10-29, 2018-10-30, 2018-10-31, 2018-11-01, 2018-11-02, 2018-11-03 on the code below return week number 44:
WeekYearRules
.FromCalendarWeekRule(
CultureInfo.InvariantCulture.DateTimeFormat.CalendarWeekRule,
CultureInfo.InvariantCulture.DateTimeFormat.FirstDayOfWeek)
.GetWeekOfWeekYear(new LocalDate(2018, 10, 28));
So it looks like there's a mismatch between the implementation of these two functions. For me it looks like the second case is giving the correct value, and maybe the first one is not taking into account the CalendarWeekRule
and the FirstDayOfWeek
.