1 | using System;
|
---|
2 | using System.Collections.Generic;
|
---|
3 | using System.Linq;
|
---|
4 | using System.Text;
|
---|
5 | using OfficeOpenXml.FormulaParsing.ExpressionGraph;
|
---|
6 |
|
---|
7 | namespace OfficeOpenXml.FormulaParsing.Excel.Functions.DateTime
|
---|
8 | {
|
---|
9 | public class IsoWeekNum : ExcelFunction
|
---|
10 | {
|
---|
11 | public override CompileResult Execute(IEnumerable<FunctionArgument> arguments, ParsingContext context)
|
---|
12 | {
|
---|
13 | ValidateArguments(arguments, 1);
|
---|
14 | var dateInt = ArgToInt(arguments, 0);
|
---|
15 | var date = System.DateTime.FromOADate(dateInt);
|
---|
16 | return CreateResult(WeekNumber(date), DataType.Integer);
|
---|
17 | }
|
---|
18 |
|
---|
19 | /// <summary>
|
---|
20 | /// This implementation was found on http://stackoverflow.com/questions/1285191/get-week-of-date-from-linq-query
|
---|
21 | /// </summary>
|
---|
22 | /// <param name="fromDate"></param>
|
---|
23 | /// <returns></returns>
|
---|
24 | private int WeekNumber(System.DateTime fromDate)
|
---|
25 | {
|
---|
26 | // Get jan 1st of the year
|
---|
27 | var startOfYear = fromDate.AddDays(-fromDate.Day + 1).AddMonths(-fromDate.Month + 1);
|
---|
28 | // Get dec 31st of the year
|
---|
29 | var endOfYear = startOfYear.AddYears(1).AddDays(-1);
|
---|
30 | // ISO 8601 weeks start with Monday
|
---|
31 | // The first week of a year includes the first Thursday
|
---|
32 | // DayOfWeek returns 0 for sunday up to 6 for saterday
|
---|
33 | int[] iso8601Correction = { 6, 7, 8, 9, 10, 4, 5 };
|
---|
34 | int nds = fromDate.Subtract(startOfYear).Days + iso8601Correction[(int)startOfYear.DayOfWeek];
|
---|
35 | int wk = nds / 7;
|
---|
36 | switch (wk)
|
---|
37 | {
|
---|
38 | case 0:
|
---|
39 | // Return weeknumber of dec 31st of the previous year
|
---|
40 | return WeekNumber(startOfYear.AddDays(-1));
|
---|
41 | case 53:
|
---|
42 | // If dec 31st falls before thursday it is week 01 of next year
|
---|
43 | if (endOfYear.DayOfWeek < DayOfWeek.Thursday)
|
---|
44 | return 1;
|
---|
45 | return wk;
|
---|
46 | default: return wk;
|
---|
47 | }
|
---|
48 | }
|
---|
49 | }
|
---|
50 | }
|
---|