.net - Incorrect ISO8601 Week Number using DatePart() -


i have following sub within class. have no errors results not match iso-8601 standards

private sub calculateallproperties(byval dt date)      select case dt.dayofweek          case dayofweek.monday              m_currentweekstartdate = dt          case dayofweek.tuesday              m_currentweekstartdate = dateadd(dateinterval.day, -1, dt)          case dayofweek.wednesday              m_currentweekstartdate = dateadd(dateinterval.day, -2, dt)          case dayofweek.thursday              m_currentweekstartdate = dateadd(dateinterval.day, -3, dt)          case dayofweek.friday              m_currentweekstartdate = dateadd(dateinterval.day, -4, dt)          case dayofweek.saturday              m_currentweekstartdate = dateadd(dateinterval.day, -5, dt)          case dayofweek.sunday              m_currentweekstartdate = dateadd(dateinterval.day, -6, dt)      end select      'now have our start point of m_currentweekstartdate can calculate other properties.      m_currentweekstartyear = datepart(dateinterval.year, m_currentweekstartdate)      m_currentweekno = datepart(dateinterval.weekofyear, m_currentweekstartdate, microsoft.visualbasic.firstdayofweek.monday, firstweekofyear.firstfourdays)      m_currentweeknoyear = currentweekno.tostring("d2") & "-" & currentweekstartyear.tostring     m_currentyearweekno = currentweekstartyear.tostring & "-" & currentweekno.tostring("d2")       m_previousweekstartdate = dateadd(dateinterval.day, -7, m_currentweekstartdate)      m_previousweekstartyear = datepart(dateinterval.year, m_previousweekstartdate)      m_previousweekno = datepart(dateinterval.weekofyear, m_previousweekstartdate, microsoft.visualbasic.firstdayofweek.monday, firstweekofyear.firstfourdays)      m_previousweeknoyear = previousweekno.tostring("d2") & "-" & previousweekstartyear.tostring     m_previousyearweekno = previousweekstartyear.tostring & "-" & previousweekno.tostring("d2")  end sub 

some example of values returned m_currentweeknoyear given date dt

  • 20/07/2015 -> 30-2015 correct
  • 09/03/2015 -> 11-2015 correct
  • 29/12/2014 -> 53-2014 incorrect should 01-2015... using 02/01/2015 gave 53-2014
  • 05/01/2015 -> 01-2015 incorrect should 02-2015... using 09/01/2015 gave 01-2015
  • 30/12/2013 -> 53-2013 incorrect should 01-2014... using 04/01/2014 gave 53-2013
  • 06/01/2014 -> 02-2014 correct

then when got year has 53 weeks works.

  • 28/12/2009 -> 53-2009 correct
  • 04/01/2010 -> 01-2010 correct

any ideas i've gone wrong?

using dateadd , datepart notoriously bad @ sort of thing, issue there (bug) inconsistency in way .net calculates week number.

see page more info iso 8601 week of year format in microsoft .net

"specifically iso 8601 has 7 day weeks. if first partial week of year doesn't contain thursday, counted last week of previous year. likewise, if last week of previous year doesn't contain thursday its[sic] treated first week of next year. getweekofyear() has first behavior, not second"

this code wrote iso 8601 week number based on definition:

"week number according iso-8601 standard, weeks starting on monday. first week of year week contains year's first thursday (='first 4-day week'). highest week number in year either 52 or 53."

''' <summary> ''' finds iso 8601 week number based on given date ''' </summary> ''' <param name="datevalue"></param> ''' <returns></returns> ''' <remarks>iso 8601 specifies monday first day of week , week 1 defined first 4 day week</remarks> public shared function getiso8601weekofyear(byval datevalue datetime) integer     return getweekofyear(datevalue, dayofweek.sunday, calendarweekrule.firstfourdayweek) end function 

it uses following more generic methods find week of year using specifics of iso standard:

'need calendar - culture's irrelevent since specify start day of week private shared cal calendar = cultureinfo.invariantculture.calendar   ''' <summary> ''' returns week number of year based on last day of week , week 1 rule ''' </summary> ''' <param name="datevalue">the date find week number for</param> ''' <param name="lastdayofweek">the last day of week</param> ''' <param name="rule">the definition of week one</param> ''' <returns>an integer specifying week number in year</returns> ''' <remarks></remarks> public shared function getweekofyear(byval datevalue datetime, byval lastdayofweek dayofweek, byval rule calendarweekrule) integer     'there bug in .net framework dates @ end of year return incorrect week number find correct value need cheat.       'find dayofweek represents first day based on last day     dim firstdayofweek dayofweek = lastdayofweek.increment     'find date of last day of week, ensures correct week number value     datevalue = getweekendingdate(datevalue, lastdayofweek)     'return value of week last day of week     return cal.getweekofyear(datevalue, rule, firstdayofweek) end function   ''' <summary> ''' finds week ending date specified date value ''' </summary> ''' <param name="datevalue">the date find week ending date for</param> ''' <param name="lastdayofweek">the last day of week</param> ''' <returns>a date value last day of week contains specified datevalue</returns> ''' <remarks></remarks> public shared function getweekendingdate(byval datevalue datetime, byval lastdayofweek dayofweek) datetime     'find out how many days difference date testing end of week     dim dayoffset integer = lastdayofweek - cal.getdayofweek(datevalue)     if dayoffset < 0 dayoffset += 7     'add days test date last day of week     return datevalue.adddays(dayoffset) end function 

this code uses extension method quick lookup find next day of week:

<extension()> public function increment(byval aday dayofweek) dayofweek     select case aday         case dayofweek.sunday : return dayofweek.monday         case dayofweek.monday : return dayofweek.tuesday         case dayofweek.tuesday : return dayofweek.wednesday         case dayofweek.wednesday : return dayofweek.thursday         case dayofweek.thursday : return dayofweek.friday         case dayofweek.friday : return dayofweek.saturday         case dayofweek.saturday : return dayofweek.sunday         case else : return nothing     end select end function 

i tried test cases , got following:

debug.writeline(getiso8601weekofyear(date.parse("20/07/2015"))) '30 debug.writeline(getiso8601weekofyear(date.parse("09/03/2015"))) '11 debug.writeline(getiso8601weekofyear(date.parse("29/12/2014"))) '1 debug.writeline(getiso8601weekofyear(date.parse("05/01/2015"))) '2 debug.writeline(getiso8601weekofyear(date.parse("30/12/2013"))) '1 debug.writeline(getiso8601weekofyear(date.parse("06/01/2014"))) '2 

Comments

Popular posts from this blog

Fail to load namespace Spring Security http://www.springframework.org/security/tags -

sql - MySQL query optimization using coalesce -

unity3d - Unity local avoidance in user created world -