Closed mm98 closed 9 years ago
I've never used Git before, so i'll add an snippet her. I've added a DayOfWeekComparer to the foreach loop, where the constructor takes a DayofWeekNum as FirstDayOfWeek. This will order the daysOfWeek foreach correctly based on FirstDayOfWeek.
Event.cs
public DayOfWeekEnum FirstDayOfWeek { get; set; }
WeeklyEventBuilder.cs
public class WeeklyEventBuilder : IEventFrequencyBuilder
{
private readonly Event _event;
public WeeklyEventBuilder(Event aEvent)
{
_event = aEvent;
}
public UnionTE Create()
{
var union = new UnionTE();
var daysOfWeek = EnumExtensions.GetFlags(_event.DaysOfWeekOptions);
var weeklyIntervals = _event.RepeatInterval;
if (weeklyIntervals > 0 && _event.StartDateTime != null)
{
foreach (DayOfWeekEnum day in daysOfWeek.Cast<DayOfWeekEnum>().OrderBy(e => e, new DayOfWeekComparer(_event.FirstDayOfWeek)))
{
var dayOfWeek = new DayInWeekTE(day, (DateTime)_event.StartDateTime, weeklyIntervals);
union.Add(dayOfWeek);
}
}
else
{
foreach (DayOfWeekEnum day in daysOfWeek.Cast<DayOfWeekEnum>().OrderBy(e => e, new DayOfWeekComparer(_event.FirstDayOfWeek)))
{
var dayOfWeek = new DayOfWeekTE(day);
union.Add(dayOfWeek);
}
}
return union;
}
}
/// Stackoverflow: "Sort by day of week" (by Colin Breame)
/// http://stackoverflow.com/a/22818999/319111
public class DayOfWeekComparer : IComparer<DayOfWeekEnum>
{
public static int Rank(DayOfWeekEnum firstDayOfWeek, DayOfWeekEnum x)
{
return (int)x + (x < firstDayOfWeek ? 128 : 0);
}
public static int Compare(DayOfWeekEnum firstDayOfWeek, DayOfWeekEnum x, DayOfWeekEnum y)
{
return Rank(firstDayOfWeek, x).CompareTo(Rank(firstDayOfWeek, y));
}
DayOfWeekEnum firstDayOfWeek;
public DayOfWeekComparer(DayOfWeekEnum firstDayOfWeek)
{
this.firstDayOfWeek = firstDayOfWeek;
}
public int Compare(DayOfWeekEnum x, DayOfWeekEnum y)
{
return DayOfWeekComparer.Compare(this.firstDayOfWeek, x, y);
}
}
DayInWeekTE also needed change, since firstDayOfWeek (Sunday) was hardcoded.
DayInWeekTE.cs (firstDayOfWeek added in constructor)
/// <summary>
/// Compares two specific days of week exactly
/// </summary>
public class DayInWeekTE : TemporalExpression
{
private readonly DayOfWeekEnum _dayOfWeek;
private readonly DayOfWeekEnum _firstDayOfWeek;
private readonly DateTime _firstDateOfWeek;
private readonly int _weeklyIntervals;
private readonly DateTime _firstDateTime;
/// <summary>
/// The day of week value
/// </summary>
/// <param name="aDayOfWeek"></param>
/// <param name="aFirstDayOfWeek"></param>
/// <param name="aFirstDateTime"></param>
/// <param name="aWeeklyInterval"></param>
public DayInWeekTE(DayOfWeekEnum aDayOfWeek, DayOfWeekEnum aFirstDayOfWeek, DateTime aFirstDateTime, int aWeeklyInterval)
{
_dayOfWeek = aDayOfWeek;
_firstDayOfWeek = aFirstDayOfWeek;
_firstDateOfWeek = StartOfWeek(aFirstDateTime, _firstDayOfWeek.GetDayOfWeek());
_weeklyIntervals = aWeeklyInterval;
_firstDateTime = aFirstDateTime;
}
/// <summary>
/// Returns true if the weekly interval and the day matches.
/// </summary>
/// <param name="aDate"></param>
/// <returns></returns>
public override bool Includes(DateTime aDate)
{
if (aDate < _firstDateTime)
{
return false;
}
return WeekMatches(aDate) && DayMatches(aDate);
}
/// <summary>
/// Returns if the day matches the specified day of week.
/// </summary>
/// <param name="dt"></param>
/// <returns></returns>
protected bool DayMatches(DateTime aDate)
{
switch (aDate.DayOfWeek)
{
case DayOfWeek.Sunday:
return ((int)_dayOfWeek == 1);
case DayOfWeek.Monday:
return ((int)_dayOfWeek == 2);
case DayOfWeek.Tuesday:
return ((int)_dayOfWeek == 4);
case DayOfWeek.Wednesday:
return ((int)_dayOfWeek == 8);
case DayOfWeek.Thursday:
return ((int)_dayOfWeek == 16);
case DayOfWeek.Friday:
return ((int)_dayOfWeek == 32);
case DayOfWeek.Saturday:
return ((int)_dayOfWeek == 64);
default:
return false;
}
}
/// <summary>
/// Returns true if the date falls in a week that matches the weekly interval.
/// </summary>
/// <param name="dt"></param>
/// <returns></returns>
protected bool WeekMatches(DateTime aDate)
{
var startOfWeek = StartOfWeek(aDate, _firstDayOfWeek.GetDayOfWeek());
double weeks = Math.Round((startOfWeek - _firstDateOfWeek).TotalDays / 7);
if (weeks % _weeklyIntervals == 0)
{
var endOfWeek = startOfWeek.AddDays(7);
if (aDate >= startOfWeek && aDate <= endOfWeek)
{
return true;
}
}
return false;
}
/// <summary>
/// Returns the first day of the week based on the provided starting day.
/// </summary>
/// <param name="dt"></param>
/// <returns></returns>
protected DateTime StartOfWeek(DateTime dt, DayOfWeek startOfWeek)
{
int diff = dt.DayOfWeek - startOfWeek;
if (diff < 0)
{
diff += 7;
}
return dt.AddDays(-1 * diff).Date;
}
}
WeeklyEventBuilder.cs (firstDayOfWeek added to DayInWeekTE constructor)
public class WeeklyEventBuilder : IEventFrequencyBuilder
{
private readonly Event _event;
public WeeklyEventBuilder(Event aEvent)
{
_event = aEvent;
}
public UnionTE Create()
{
var union = new UnionTE();
var daysOfWeek = EnumExtensions.GetFlags(_event.DaysOfWeekOptions);
var weeklyIntervals = _event.RepeatInterval;
if (weeklyIntervals > 0 && _event.StartDateTime != null)
{
foreach (DayOfWeekEnum day in daysOfWeek.Cast<DayOfWeekEnum>().OrderBy(e => e, new DayOfWeekEnumComparer(_event.FirstDayOfWeek)))
{
var dayOfWeek = new DayInWeekTE(day, _event.FirstDayOfWeek, (DateTime)_event.StartDateTime, weeklyIntervals);
union.Add(dayOfWeek);
}
}
else
{
foreach (DayOfWeekEnum day in daysOfWeek.Cast<DayOfWeekEnum>().OrderBy(e => e, new DayOfWeekEnumComparer(_event.FirstDayOfWeek)))
{
var dayOfWeek = new DayOfWeekTE(day);
union.Add(dayOfWeek);
}
}
return union;
}
}
public class DayOfWeekEnumComparer : IComparer<DayOfWeekEnum>
{
public static int Rank(DayOfWeekEnum firstDayOfWeek, DayOfWeekEnum x)
{
return (int)x + (x < firstDayOfWeek ? 128 : 0);
}
public static int Compare(DayOfWeekEnum firstDayOfWeek, DayOfWeekEnum x, DayOfWeekEnum y)
{
return Rank(firstDayOfWeek, x).CompareTo(Rank(firstDayOfWeek, y));
}
DayOfWeekEnum firstDayOfWeek;
public DayOfWeekEnumComparer(DayOfWeekEnum firstDayOfWeek)
{
this.firstDayOfWeek = firstDayOfWeek;
}
public int Compare(DayOfWeekEnum x, DayOfWeekEnum y)
{
return DayOfWeekEnumComparer.Compare(this.firstDayOfWeek, x, y);
}
}
EnumExtensions.cs (added DayOfWeekEnum > System.DayOfWeek extension)
internal static class EnumExtensions
{
public const int MonthlyIntervalMaxBitField = 31;
public const int FrequencyTypeMaxBitField = 7;
public const int DayOfWeekMaxBitField = 127;
public static IEnumerable<Enum> GetFlags(Enum input)
{
foreach (Enum value in Enum.GetValues(input.GetType()))
if (input.HasFlag(value))
yield return value;
}
public static DayOfWeek GetDayOfWeek(this DayOfWeekEnum dayOfWeek)
{
switch (dayOfWeek)
{
case DayOfWeekEnum.Sun:
return DayOfWeek.Sunday;
case DayOfWeekEnum.Mon:
return DayOfWeek.Monday;
case DayOfWeekEnum.Tue:
return DayOfWeek.Tuesday;
case DayOfWeekEnum.Wed:
return DayOfWeek.Wednesday;
case DayOfWeekEnum.Thu:
return DayOfWeek.Thursday;
case DayOfWeekEnum.Fri:
return DayOfWeek.Friday;
case DayOfWeekEnum.Sat:
return DayOfWeek.Saturday;
}
return DayOfWeek.Sunday;
}
}
Hi,
Currently ScheduleWidget is based on weekstart sunday. There is no way to defined weekstart ex. monday. Would be great to have this option for EU users =)
Its a problem when selecting every day (mon to sun), with Weekly option and repeat interval = 2. Possibly a way to define it by param or CultureInfo?