c# - How to do I invert the week returned from Calendar.GetWeekOfYear back to a DateTime? -


this question has answer here:

the problem there not seem built-in way datetime calculated "week number".

what want have work times , cultural calendars.

  datetime dt1 = new datetime.now;   int week = cal.getweekofyear(dt);   datetime dt2 = getdatetimefromyearandweek(dt.year, week);    if (dt1 < dt2 || dt2 > dt2.adddays(7.0))   {     throw new exception("new datetime limits not span existing datetime;   } 

i think 1 of issues cultures, cal.getweekofyear(dt) call return correct week number different year dt.year. means can't use in call fictious getdatetimefromyearandweek call.

my own answer three-fold. first, came wrapper calendar.getweekofyear returns "year" of week, since year may not same year of datetime object.

    public static void getweek(datetime dt, cultureinfo ci, out int week, out int year)     {         year = dt.year;         week = ci.calendar.getweekofyear(dt, ci.datetimeformat.calendarweekrule, ci.datetimeformat.firstdayofweek);          int prevweek = ci.calendar.getweekofyear(dt.adddays(-7.0), ci.datetimeformat.calendarweekrule, ci.datetimeformat.firstdayofweek);          if (prevweek + 1 == week) {             // year of prevweek should correct             year = dt.adddays(-7.0).year;         } else {             // stay here             year = dt.year;         }     } 

next, here meat of answer. inverts year , weekofyear datetime object. note used middle of year, because seems avoid problems singularities of new year (where 52 or 53 may or not wrap around 1). synchronize date finding date indeed first day of week, avoiding problems negative offsets comparing 2 dayofweek values.

    public static datetime firstdateofweek(int year, int weekofyear, cultureinfo ci)     {         datetime jul1 = new datetime(year, 7, 1);         while (jul1.dayofweek != ci.datetimeformat.firstdayofweek)         {             jul1 = jul1.adddays(1.0);         }         int refweek = ci.calendar.getweekofyear(jul1, ci.datetimeformat.calendarweekrule, ci.datetimeformat.firstdayofweek);          int weekoffset = weekofyear - refweek;          return jul1.adddays(7 * weekoffset );     } 

and doubt it, here unit test cycles through lots of dates , cultures make sure works on of them.

    public static void testdates()     {         foreach (cultureinfo ci in cultureinfo.getcultures(culturetypes.allcultures).where((x)=>!x.isneutralculture && x.calendar.algorithmtype == calendaralgorithmtype.solarcalendar))         {              (int year = 2010; year < 2040; year++)             {                 // first try bunch of hours in year                 // convert date -> week -> date                  (int hour = 0; hour < 356 * 24; hour+= 6)                 {                     datetime dt = new datetime(year, 1, 1).addhours(hour);                     int ww;                     int wyear;                     gener8.serialnumber.getweek(dt, ci, out ww, out wyear);                     if (wyear != year)                     {                         //console.writeline("{0} warning: {1} {2} {3}", ci.name, dt, year, wyear);                     }                     datetime dt1 = gener8.serialnumber.firstdateofweek(wyear, ww, ci);                     datetime dt2 = gener8.serialnumber.firstdateofweek(wyear, ww, ci).adddays(7.0);                     if (dt < dt1 || dt > dt2)                     {                         console.writeline("{3} bad date {0} not between {1} , {2}", dt, dt1, dt2, ci.name);                     }                 }                  // next try bunch of weeks in year                 // convert week -> date -> week                  (int week = 1; week < 54; week++)                 {                     datetime dt0 = firstdateofweek(year, week, ci);                     int ww0;                     int wyear0;                     getweek(dt0, ci, out ww0, out wyear0);                     datetime dt1 = dt0.adddays(6.9);                     int ww1;                     int wyear1;                     getweek(dt1, ci, out ww1, out wyear1);                     if ((dt0.year == year && ww0 != week) ||                         (dt1.year == year && ww1 != week))                     {                         console.writeline("{4} bad date {0} ww0={1} ww1={2}, week={3}", dt0, ww0, ww1, week, ci.name);                     }                 }             }         }     } 

Comments

Popular posts from this blog

jquery - How can I dynamically add a browser tab? -

node.js - Getting the socket id,user id pair of a logged in user(s) -

keyboard - C++ GetAsyncKeyState alternative -