using System; using System.Collections.Generic; using System.Linq; using System.Text; using OfficeOpenXml.FormulaParsing.ExpressionGraph; namespace OfficeOpenXml.FormulaParsing.Excel.Functions.DateTime { public class IsoWeekNum : ExcelFunction { public override CompileResult Execute(IEnumerable arguments, ParsingContext context) { ValidateArguments(arguments, 1); var dateInt = ArgToInt(arguments, 0); var date = System.DateTime.FromOADate(dateInt); return CreateResult(WeekNumber(date), DataType.Integer); } /// /// This implementation was found on http://stackoverflow.com/questions/1285191/get-week-of-date-from-linq-query /// /// /// private int WeekNumber(System.DateTime fromDate) { // Get jan 1st of the year var startOfYear = fromDate.AddDays(-fromDate.Day + 1).AddMonths(-fromDate.Month + 1); // Get dec 31st of the year var endOfYear = startOfYear.AddYears(1).AddDays(-1); // ISO 8601 weeks start with Monday // The first week of a year includes the first Thursday // DayOfWeek returns 0 for sunday up to 6 for saterday int[] iso8601Correction = { 6, 7, 8, 9, 10, 4, 5 }; int nds = fromDate.Subtract(startOfYear).Days + iso8601Correction[(int)startOfYear.DayOfWeek]; int wk = nds / 7; switch (wk) { case 0: // Return weeknumber of dec 31st of the previous year return WeekNumber(startOfYear.AddDays(-1)); case 53: // If dec 31st falls before thursday it is week 01 of next year if (endOfYear.DayOfWeek < DayOfWeek.Thursday) return 1; return wk; default: return wk; } } } }