LocalDate from Week and WeekYear

2019-02-22 07:14发布

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

标签: c# nodatime
2条回答
【Aperson】
2楼-- · 2019-02-22 07:19

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);
查看更多
Evening l夕情丶
3楼-- · 2019-02-22 07:24

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.

查看更多
登录 后发表回答