week comparisons help please

  • Thread starter Thread starter rodchar
  • Start date Start date
R

rodchar

hey all,
let's say i had a week range of 2008/4 - 2007/50.
sample data:
year,week
2008,5
2007,52
2007,48

what would be the easiest way to determine if the data coming in is
less than 2007/50,
between 2007/50-2008/4
greater than 2008/4

thanks,
rodchar
 
rodchar said:
hey all,
let's say i had a week range of 2008/4 - 2007/50.
sample data:
year,week
2008,5
2007,52
2007,48

what would be the easiest way to determine if the data coming in is
less than 2007/50,
between 2007/50-2008/4
greater than 2008/4

thanks,
rodchar


To compare two objects of a YearWeek type, first look at the year. if there
is any difference, then it is easy to see which is bigger. If the years are
identical, just do the compares on the week.

To test for betweenness, just check if RangeStart < test and test <
RangeEnd.
 
rodchar said:
let's say i had a week range of 2008/4 - 2007/50.
sample data:
year,week
2008,5
2007,52
2007,48

what would be the easiest way to determine if the data coming in is
less than 2007/50,
between 2007/50-2008/4
greater than 2008/4

You can use some of the code I gave you in your previous
week question.

Arne
 
thanks everyone for the feedback.

Arne,
thanks for reminding me, i do have that saved. at first, it looks a little
over my head but the more and more research i do it's starting to make a
little sense to me, forgive my ignorance.

And the more sense it starts to make the more interesting it becomes to me.
thanks for the time and effort. if you don't mind, i'm going to study your
code more and if i have more questions i'll post here.
 
Arne,
I already have a question:

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);
}

i'm not sure i know what the above is? are these methods?
 
rodchar said:
I already have a question:

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);
}

i'm not sure i know what the above is? are these methods?

They define the == and != operator for the YearWeek struct, so
you can do:

if(yw1 == yw2)

if(yw1 != yw2)

One way of solving your problems is to add >, <, >= and <=
operators.

Arne
 
Is there a way to get exact date ranges from the week number?
for instance,
2008/1 = Jan 1, 08 - Jan 6, 08 (not exactly sure if that constitues a week
but nevertheless)
 
hi,

public static int GetWeekNumber(DateTime dtPassed)
{
CultureInfo ciCurr = CultureInfo.CurrentCulture;
int weekNum = ciCurr.Calendar.GetWeekOfYear(dtPassed,
CalendarWeekRule.FirstFourDayWeek, DayOfWeek.Monday);
return weekNum;
}

i'd like to make this part of my YearWeek struct. Is it possible to change
this so it will return an instance of YearWeek?
 
rodchar said:
Is there a way to get exact date ranges from the week number?
for instance,
2008/1 = Jan 1, 08 - Jan 6, 08 (not exactly sure if that constitues a week
but nevertheless)

Yes.

Given a specific week numbering rule, then it is obvious
possible.

Below are code (still only implemented for ISO week numbers).

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 static DayInterval ToInterval(WeekType typ, YearWeek yw)
{
DateTime dt = ToDate(typ, yw);
DateTime start = dt;
while (FromDate(typ, start.AddDays(-1)) == yw)
{
start = start.AddDays(-1);
}
DateTime end = dt;
while (FromDate(typ, end.AddDays(1)) == yw)
{
end = end.AddDays(1);
}
end =
end.AddHours(23).AddMinutes(59).AddSeconds(59).AddMilliseconds(999);
return new DayInterval(start, end);
}
}
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 struct DayInterval
{
private DateTime start;
private DateTime end;
public DateTime Start { get { return start; } }
public DateTime End { get { return end; } }
public DayInterval(DateTime start, DateTime end)
{
this.start = start;
this.end = end;
}
public override string ToString()
{
return start + "-" + end;
}
}
public class Program
{
public static void Main(string[] args)
{
YearWeek now = WeekUtil.FromDate(WeekType.ISO, DateTime.Now);
Console.WriteLine(now);
Console.WriteLine(WeekUtil.ToInterval(WeekType.ISO, now));
Console.ReadKey();
}
}
}
 
rodchar said:
public static int GetWeekNumber(DateTime dtPassed)
{
CultureInfo ciCurr = CultureInfo.CurrentCulture;
int weekNum = ciCurr.Calendar.GetWeekOfYear(dtPassed,
CalendarWeekRule.FirstFourDayWeek, DayOfWeek.Monday);
return weekNum;
}

i'd like to make this part of my YearWeek struct. Is it possible to change
this so it will return an instance of YearWeek?

You should add it as a WeekType to th WeekUtil class.

Note though that the above is specifying ISO week, but it
is not working correctly.

See code below.

Arne

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

using System;
using System.Globalization;

namespace E
{
public enum WeekType { ISO, WRONGISO };
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;
}
private static int WrongIsoWeek(DateTime dt)
{
CultureInfo ci = CultureInfo.CurrentCulture;
return ci.Calendar.GetWeekOfYear(dt,
CalendarWeekRule.FirstFourDayWeek, DayOfWeek.Monday);
}
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;
case WeekType.WRONGISO:
w = WrongIsoWeek(dt);
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 static DayInterval ToInterval(WeekType typ, YearWeek yw)
{
DateTime dt = ToDate(typ, yw);
DateTime start = dt;
while (FromDate(typ, start.AddDays(-1)) == yw)
{
start = start.AddDays(-1);
}
DateTime end = dt;
while (FromDate(typ, end.AddDays(1)) == yw)
{
end = end.AddDays(1);
}
end =
end.AddHours(23).AddMinutes(59).AddSeconds(59).AddMilliseconds(999);
return new DayInterval(start, end);
}
}
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 struct DayInterval
{
private DateTime start;
private DateTime end;
public DateTime Start { get { return start; } }
public DateTime End { get { return end; } }
public DayInterval(DateTime start, DateTime end)
{
this.start = start;
this.end = end;
}
public override string ToString()
{
return start + "-" + end;
}
}
public class Program
{
public static void Main(string[] args)
{
DateTime dt1 = new DateTime(2003, 12, 31);
Console.WriteLine(dt1);
Console.WriteLine(WeekUtil.FromDate(WeekType.ISO, dt1));
Console.WriteLine(WeekUtil.ToInterval(WeekType.ISO,
WeekUtil.FromDate(WeekType.ISO, dt1)));
Console.WriteLine(WeekUtil.FromDate(WeekType.WRONGISO, dt1));
Console.WriteLine(WeekUtil.ToInterval(WeekType.WRONGISO,
WeekUtil.FromDate(WeekType.WRONGISO, dt1)));
DateTime dt2 = new DateTime(2004, 1, 1);
Console.WriteLine(dt2);
Console.WriteLine(WeekUtil.FromDate(WeekType.ISO, dt2));
Console.WriteLine(WeekUtil.ToInterval(WeekType.ISO,
WeekUtil.FromDate(WeekType.ISO, dt2)));
Console.WriteLine(WeekUtil.FromDate(WeekType.WRONGISO, dt2));
Console.WriteLine(WeekUtil.ToInterval(WeekType.WRONGISO,
WeekUtil.FromDate(WeekType.WRONGISO, dt2)));
Console.ReadKey();
}
}
}
 
hmm, not sure i'll try to find out.

Paul E Collins said:
I don't think it's in the Framework, but it doesn't sound difficult to code.
Remember that, once you have a DateTime instance, you can do .AddDays on it
to get earlier and later dates.

What's your definition of "week 1"? Does it start on 1 January, or the first
Monday of the year, or...?

Eq.
 
thanks Arne, i'm going to have some take some time to soak all this in. when
you say ISO week what does that mean? as oppose to?

Arne Vajhøj said:
rodchar said:
public static int GetWeekNumber(DateTime dtPassed)
{
CultureInfo ciCurr = CultureInfo.CurrentCulture;
int weekNum = ciCurr.Calendar.GetWeekOfYear(dtPassed,
CalendarWeekRule.FirstFourDayWeek, DayOfWeek.Monday);
return weekNum;
}

i'd like to make this part of my YearWeek struct. Is it possible to change
this so it will return an instance of YearWeek?

You should add it as a WeekType to th WeekUtil class.

Note though that the above is specifying ISO week, but it
is not working correctly.

See code below.

Arne

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

using System;
using System.Globalization;

namespace E
{
public enum WeekType { ISO, WRONGISO };
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;
}
private static int WrongIsoWeek(DateTime dt)
{
CultureInfo ci = CultureInfo.CurrentCulture;
return ci.Calendar.GetWeekOfYear(dt,
CalendarWeekRule.FirstFourDayWeek, DayOfWeek.Monday);
}
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;
case WeekType.WRONGISO:
w = WrongIsoWeek(dt);
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 static DayInterval ToInterval(WeekType typ, YearWeek yw)
{
DateTime dt = ToDate(typ, yw);
DateTime start = dt;
while (FromDate(typ, start.AddDays(-1)) == yw)
{
start = start.AddDays(-1);
}
DateTime end = dt;
while (FromDate(typ, end.AddDays(1)) == yw)
{
end = end.AddDays(1);
}
end =
end.AddHours(23).AddMinutes(59).AddSeconds(59).AddMilliseconds(999);
return new DayInterval(start, end);
}
}
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 struct DayInterval
{
private DateTime start;
private DateTime end;
public DateTime Start { get { return start; } }
public DateTime End { get { return end; } }
public DayInterval(DateTime start, DateTime end)
{
this.start = start;
this.end = end;
}
public override string ToString()
{
return start + "-" + end;
}
}
public class Program
{
public static void Main(string[] args)
{
DateTime dt1 = new DateTime(2003, 12, 31);
Console.WriteLine(dt1);
Console.WriteLine(WeekUtil.FromDate(WeekType.ISO, dt1));
Console.WriteLine(WeekUtil.ToInterval(WeekType.ISO,
WeekUtil.FromDate(WeekType.ISO, dt1)));
Console.WriteLine(WeekUtil.FromDate(WeekType.WRONGISO, dt1));
Console.WriteLine(WeekUtil.ToInterval(WeekType.WRONGISO,
WeekUtil.FromDate(WeekType.WRONGISO, dt1)));
DateTime dt2 = new DateTime(2004, 1, 1);
Console.WriteLine(dt2);
Console.WriteLine(WeekUtil.FromDate(WeekType.ISO, dt2));
Console.WriteLine(WeekUtil.ToInterval(WeekType.ISO,
WeekUtil.FromDate(WeekType.ISO, dt2)));
Console.WriteLine(WeekUtil.FromDate(WeekType.WRONGISO, dt2));
Console.WriteLine(WeekUtil.ToInterval(WeekType.WRONGISO,
WeekUtil.FromDate(WeekType.WRONGISO, dt2)));
Console.ReadKey();
}
}
}
 
Arne,
why did you pick a struct over class for YearWeek?

rodchar said:
thanks Arne, i'm going to have some take some time to soak all this in. when
you say ISO week what does that mean? as oppose to?

Arne Vajhøj said:
rodchar said:
public static int GetWeekNumber(DateTime dtPassed)
{
CultureInfo ciCurr = CultureInfo.CurrentCulture;
int weekNum = ciCurr.Calendar.GetWeekOfYear(dtPassed,
CalendarWeekRule.FirstFourDayWeek, DayOfWeek.Monday);
return weekNum;
}

i'd like to make this part of my YearWeek struct. Is it possible to change
this so it will return an instance of YearWeek?

You should add it as a WeekType to th WeekUtil class.

Note though that the above is specifying ISO week, but it
is not working correctly.

See code below.

Arne

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

using System;
using System.Globalization;

namespace E
{
public enum WeekType { ISO, WRONGISO };
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;
}
private static int WrongIsoWeek(DateTime dt)
{
CultureInfo ci = CultureInfo.CurrentCulture;
return ci.Calendar.GetWeekOfYear(dt,
CalendarWeekRule.FirstFourDayWeek, DayOfWeek.Monday);
}
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;
case WeekType.WRONGISO:
w = WrongIsoWeek(dt);
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 static DayInterval ToInterval(WeekType typ, YearWeek yw)
{
DateTime dt = ToDate(typ, yw);
DateTime start = dt;
while (FromDate(typ, start.AddDays(-1)) == yw)
{
start = start.AddDays(-1);
}
DateTime end = dt;
while (FromDate(typ, end.AddDays(1)) == yw)
{
end = end.AddDays(1);
}
end =
end.AddHours(23).AddMinutes(59).AddSeconds(59).AddMilliseconds(999);
return new DayInterval(start, end);
}
}
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 struct DayInterval
{
private DateTime start;
private DateTime end;
public DateTime Start { get { return start; } }
public DateTime End { get { return end; } }
public DayInterval(DateTime start, DateTime end)
{
this.start = start;
this.end = end;
}
public override string ToString()
{
return start + "-" + end;
}
}
public class Program
{
public static void Main(string[] args)
{
DateTime dt1 = new DateTime(2003, 12, 31);
Console.WriteLine(dt1);
Console.WriteLine(WeekUtil.FromDate(WeekType.ISO, dt1));
Console.WriteLine(WeekUtil.ToInterval(WeekType.ISO,
WeekUtil.FromDate(WeekType.ISO, dt1)));
Console.WriteLine(WeekUtil.FromDate(WeekType.WRONGISO, dt1));
Console.WriteLine(WeekUtil.ToInterval(WeekType.WRONGISO,
WeekUtil.FromDate(WeekType.WRONGISO, dt1)));
DateTime dt2 = new DateTime(2004, 1, 1);
Console.WriteLine(dt2);
Console.WriteLine(WeekUtil.FromDate(WeekType.ISO, dt2));
Console.WriteLine(WeekUtil.ToInterval(WeekType.ISO,
WeekUtil.FromDate(WeekType.ISO, dt2)));
Console.WriteLine(WeekUtil.FromDate(WeekType.WRONGISO, dt2));
Console.WriteLine(WeekUtil.ToInterval(WeekType.WRONGISO,
WeekUtil.FromDate(WeekType.WRONGISO, dt2)));
Console.ReadKey();
}
}
}
 
rodchar said:
why did you pick a struct over class for YearWeek?

It seemed as a value type to me.

:-)

Week number according to ISO 8601 standard as opposed to US standard.

Arne
 
Back
Top