year/week calculation

R

rodchar

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
 
M

Michael A. Covington

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

TAB

As Microsofts weeknumber has bug you can't use the built in
Calendar.GetWeekOfYear 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(DateTime fromDate)
{
// Get jan 1st of the year
DateTime startOfYear = fromDate.AddDays(-fromDate.Day +
1).AddMonths(-fromDate.Month + 1);
// Get dec 31st of the year
DateTime endOfYear = startOfYear.AddYears(1).AddDays(-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[] 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;
else
return wk;
default: return wk;
}
}
 
A

Arne Vajhøj

rodchar said:
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.FromDate.

Arne

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

using System;
using System.Globalization;

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(WeekType 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 ArgumentOutOfRangeException("Unknown 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.Year, 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(WeekType typ, int y, int w)
{
this.typ = typ;
this.y = y;
this.w = w;
}
public YearWeek AddWeeks(int n)
{
return WeekUtil.FromDate(typ, WeekUtil.ToDate(typ,
this).AddDays(n * 7));
}
public override string ToString()
{
return Year.ToString("0000") + "w" + Week.ToString("00");
}
public static bool operator==(YearWeek a, YearWeek b)
{
return a.Year == b.Year && a.Week == b.Week;
}
public static bool operator!=(YearWeek 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(WeekType.ISO, 2008, 16);
for (int i = 0; i <= 26; i++)
{
Console.WriteLine(yw + "->" + yw.AddWeeks(-i));
}
Console.ReadKey();
}
}
}
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top