year/week calculation

Collapse
This topic is closed.
X
X
 
  • Time
  • Show
Clear All
new posts
  • =?Utf-8?B?cm9kY2hhcg==?=

    year/week calculation

    hey all,
    is there a way if you are given a Year and a Week an easy way to go back say
    26 weeks ago from given year/week.

    for example,
    given: 2008/16
    26 weeks prior is:
    2007/43

    thanks,
    rodchar
  • Michael A. Covington

    #2
    Re: year/week calculation

    Since the length of a year is not a multiple of 7 days, the problem seems
    ill-defined.

    "rodchar" <rodchar@discus sions.microsoft .comwrote in message
    news:E71EE228-8D2E-4C50-B650-F984A0398D3D@mi crosoft.com...
    hey all,
    is there a way if you are given a Year and a Week an easy way to go back
    say
    26 weeks ago from given year/week.
    >
    for example,
    given: 2008/16
    26 weeks prior is:
    2007/43
    >
    thanks,
    rodchar
    >

    Comment

    • TAB

      #3
      Re: year/week calculation

      As Microsofts weeknumber has bug you can't use the built in
      Calendar.GetWee kOfYear because that won't
      return the correct ISO8601 week number.

      I'm using this replacement. One way to use it is to subtract 1 day at a time
      and count weeks until
      you found the date you are looking for.


      // get week number for current date
      public int WeekNumber(Date Time fromDate)
      {
      // Get jan 1st of the year
      DateTime startOfYear = fromDate.AddDay s(-fromDate.Day +
      1).AddMonths(-fromDate.Month + 1);
      // Get dec 31st of the year
      DateTime endOfYear = startOfYear.Add Years(1).AddDay s(-1);
      // ISO 8601 weeks start with Monday
      // The first week of a year includes the first Thursday, i.e. at
      least 4 days
      // DayOfWeek returns 0 for sunday up to 6 for Saturday
      int[] iso8601Correcti on = { 6, 7, 8, 9, 10, 4, 5 };
      int nds = fromDate.Subtra ct(startOfYear) .Days +
      iso8601Correcti on[(int)startOfYea r.DayOfWeek];
      int wk = nds / 7;
      switch (wk)
      {
      case 0:
      // Return weeknumber of dec 31st of the previous year
      return WeekNumber(star tOfYear.AddDays (-1));
      case 53:
      // If dec 31st falls before thursday it is week 01 of
      next year
      if (endOfYear.DayO fWeek < DayOfWeek.Thurs day)
      return 1;
      else
      return wk;
      default: return wk;
      }
      }

      "rodchar" <rodchar@discus sions.microsoft .comskrev i meddelandet
      news:E71EE228-8D2E-4C50-B650-F984A0398D3D@mi crosoft.com...
      hey all,
      is there a way if you are given a Year and a Week an easy way to go back
      say
      26 weeks ago from given year/week.
      >
      for example,
      given: 2008/16
      26 weeks prior is:
      2007/43
      >
      thanks,
      rodchar

      Comment

      • =?UTF-8?B?QXJuZSBWYWpow7hq?=

        #4
        Re: year/week calculation

        rodchar wrote:
        hey all,
        is there a way if you are given a Year and a Week an easy way to go back say
        26 weeks ago from given year/week.
        >
        for example,
        given: 2008/16
        26 weeks prior is:
        2007/43
        With ISO week numbering I actually get 2007/42.

        Below are some code. You will need to add week
        numbering scheme if you are not using ISO - just
        add value to enum WeekType and case to switch in
        WeekUtil.FromDa te.

        Arne

        =============== =============

        using System;
        using System.Globaliz ation;

        namespace E
        {
        public enum WeekType { ISO };
        public static class WeekUtil
        {
        private static int IsoWeek(int year, int mon, int day)
        {
        int a = (14 - mon) / 12;
        int y = year + 4800 - a;
        int m = mon + 12*a - 3;
        int JD = day + (153 * m + 2)/5 + 365*y + y/4 - y/100 +
        y/400 - 32045;
        int d4 = (((JD + 31741 - JD % 7) % 146097) % 36524) % 1461;
        int L = d4 / 1460;
        int d1 = ((d4 - L) % 365) + L;
        return d1 / 7 + 1;
        }
        public static YearWeek FromDate(WeekTy pe typ, DateTime dt)
        {
        int y;
        int w;
        y = dt.Year;
        switch (typ) {
        case WeekType.ISO:
        w = IsoWeek(dt.Year , dt.Month, dt.Day);
        break;
        default:
        throw new ArgumentOutOfRa ngeException("U nknown week
        type");
        }
        if(w == 1 && dt.Month == 12) y++;
        if(w >= 52 && dt.Month == 1) y--;
        return new YearWeek(typ, y, w);
        }
        public static DateTime ToDate(WeekType typ, YearWeek yw)
        {
        DateTime dt = new DateTime(yw.Yea r, 1, 7);
        dt = dt.AddDays((yw. Week - FromDate(typ, dt).Week) * 7);
        return dt;
        }
        }
        public struct YearWeek
        {
        private WeekType typ;
        private int y;
        private int w;
        public int Year { get { return y; } }
        public int Week { get { return w;} }
        public YearWeek(WeekTy pe typ, int y, int w)
        {
        this.typ = typ;
        this.y = y;
        this.w = w;
        }
        public YearWeek AddWeeks(int n)
        {
        return WeekUtil.FromDa te(typ, WeekUtil.ToDate (typ,
        this).AddDays(n * 7));
        }
        public override string ToString()
        {
        return Year.ToString(" 0000") + "w" + Week.ToString(" 00");
        }
        public static bool operator==(Year Week a, YearWeek b)
        {
        return a.Year == b.Year && a.Week == b.Week;
        }
        public static bool operator!=(Year Week a, YearWeek b)
        {
        return !(a == b);
        }
        public override bool Equals(object obj)
        {
        return this == (YearWeek)obj;
        }
        public override int GetHashCode()
        {
        return y.GetHashCode() ^ w.GetHashCode() ;
        }
        }
        public class Program
        {
        public static void Main(string[] args)
        {
        YearWeek yw = new YearWeek(WeekTy pe.ISO, 2008, 16);
        for (int i = 0; i <= 26; i++)
        {
        Console.WriteLi ne(yw + "->" + yw.AddWeeks(-i));
        }
        Console.ReadKey ();
        }
        }
        }

        Comment

        Working...