using System; using System.Collections.Generic; using System.Globalization; using System.Linq; using System.Text; using System.Threading.Tasks; namespace EgwCoreLib.Razor.Data { public class WeekData { public int anno { get; set; } = DateTime.Today.Year; public DateTime inizio { get; set; } = DateTime.Today; public DateTime fine { get; set; } = DateTime.Today.AddDays(1); public int weekNumber { get; set; } = 1; /// /// Calcola estremi settimana dato un giorno come lunedì-domenica /// /// public WeekData(DateTime dtRif) { DayOfWeek day = CultureInfo.InvariantCulture.Calendar.GetDayOfWeek(dtRif); // attenzione: è domenica = 0 --> in quel caso va portato a 7!!! int numDay = day == DayOfWeek.Sunday ? 7 : (int)day; this.weekNumber = GetIso8601WeekOfYear(dtRif); this.inizio = dtRif.Date.AddDays(1 - numDay); this.anno = inizio.Year; this.fine = dtRif.Date.AddDays(7 - numDay); } /// /// Calcola estremi settimana dato numero + anno /// /// public WeekData(int year, int numWeek) { this.anno = year; this.weekNumber = numWeek; DateTime dtRif = FirstDateOfWeekISO8601(year, numWeek); DayOfWeek day = CultureInfo.InvariantCulture.Calendar.GetDayOfWeek(dtRif); this.inizio = dtRif.Date.AddDays(1 - (int)day); this.fine = dtRif.Date.AddDays(7 - (int)day); } /// /// Calcolo settimana dell'anno ISO 8601 /// /// This presumes that weeks start with Monday. /// Week 1 is the 1st week of the year with a Thursday in it. /// /// rif: https://stackoverflow.com/questions/11154673/get-the-correct-week-number-of-a-given-date /// /// /// public static int GetIso8601WeekOfYear(DateTime time) { // Seriously cheat. If its Monday, Tuesday or Wednesday, then it'll // be the same week# as whatever Thursday, Friday or Saturday are, // and we always get those right DayOfWeek day = CultureInfo.InvariantCulture.Calendar.GetDayOfWeek(time); if (day >= DayOfWeek.Monday && day <= DayOfWeek.Wednesday) { time = time.AddDays(3); } // Return the week of our adjusted day return CultureInfo.InvariantCulture.Calendar.GetWeekOfYear(time, CalendarWeekRule.FirstFourDayWeek, DayOfWeek.Monday); } public static DateTime FirstDateOfWeekISO8601(int year, int weekOfYear) { DateTime jan1 = new DateTime(year, 1, 1); int daysOffset = DayOfWeek.Thursday - jan1.DayOfWeek; // Use first Thursday in January to get first week of the year as // it will never be in Week 52/53 DateTime firstThursday = jan1.AddDays(daysOffset); var cal = CultureInfo.CurrentCulture.Calendar; int firstWeek = cal.GetWeekOfYear(firstThursday, CalendarWeekRule.FirstFourDayWeek, DayOfWeek.Monday); var weekNum = weekOfYear; // As we're adding days to a date in Week 1, // we need to subtract 1 in order to get the right date for week #1 if (firstWeek == 1) { weekNum -= 1; } // Using the first Thursday as starting week ensures that we are starting in the right year // then we add number of weeks multiplied with days var result = firstThursday.AddDays(weekNum * 7); // Subtract 3 days from Thursday to get Monday, which is the first weekday in ISO8601 return result.AddDays(-3); } } }