using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using QgOne.Core;
namespace DateTimeTests
{
[Settable, Serializable]
public class MDateTime
{
#region Category definitions
public enum YearCategory { Min = 1, CommonYear = 2009, LeapYear = 2012, CommonCentury = 1900, LeapCentury = 2000, Max = 9999 }
public enum MonthCategory { Jan = 1, Feb = 2, Jun = 6, Jul = 7, Aug = 8, Dec = 12 }
public enum DayCategory { First, SecondLast, Last }
public enum TimeCategory { Min = 0, Mid = 30, Max = 59 }
#endregion Category definitions
#region Factors
public YearCategory Year { get; set; }
public MonthCategory Month { get; set; }
public DayCategory Day { get; set; }
public TimeCategory Hour { get; set; }
public TimeCategory Minute { get; set; }
public TimeCategory Second { get; set; }
public TimeCategory Millisecond { get; set; }
#endregion Factors
#region Days in ...
public int DaysInMonth
{
get
{
return DaysInFutureMonth(new MTimeSpan { Days = MTimeSpan.DayCategory.Zero });
}
}
public int DaysInFutureMonth(MTimeSpan ts)
{
switch (Month)
{
case MonthCategory.Jan:
case MonthCategory.Jul:
case MonthCategory.Aug:
case MonthCategory.Dec:
return 31;
case MonthCategory.Jun:
return 30;
case MonthCategory.Feb:
if (ts.Days == MTimeSpan.DayCategory.Year || ts.Days == MTimeSpan.DayCategory.YearAndOneDay)
{
return 28;
}
else if (Year == YearCategory.LeapCentury || Year == YearCategory.LeapYear)
{
return 29;
}
else
{
return 28;
}
}
throw new ArgumentException(string.Format("Unable to resolve days in month for month = {0} and year = {1}", Month, Year));
}
public int DaysInYear
{
get
{
// Days in forward year: Is only 366 if leap year and month is Jan or Feb
if ((Month == MonthCategory.Jan || Month == MonthCategory.Feb) &&
(Year == YearCategory.LeapYear || Year == YearCategory.LeapCentury))
{
return 366;
}
else
{
return 365;
}
}
}
#endregion Days in ...
#region Resolve
private int ResolveDay()
{
switch (Day)
{
case DayCategory.First:
return 1;
case DayCategory.SecondLast:
return DaysInMonth - 1;
case DayCategory.Last:
return DaysInMonth;
}
throw new ArgumentException(string.Format("Unable to resolve day for {0}/{1} {2}", Day, Month, Year));
}
private int ResolveTimeCategory(TimeCategory tc, int minValue, int midValue, int maxValue)
{
switch (tc)
{
case TimeCategory.Min:
return minValue;
case TimeCategory.Mid:
{
Random prng = new Random();
return prng.Next(minValue + 1, maxValue);
}
case TimeCategory.Max:
return maxValue;
}
throw new ArgumentException(string.Format("Unable to resolve time category {0}", tc));
}
public void Resolve()
{
int year = (int)Year;
int month = (int)Month;
int day = ResolveDay();
int hour = ResolveTimeCategory(Hour, 0, 12, 23);
int min = ResolveTimeCategory(Minute, 0, 30, 59);
int sec = ResolveTimeCategory(Second, 0, 30, 59);
int msec = ResolveTimeCategory(Millisecond, 0, 500, 999);
Value = new DateTime(year, month, day, hour, min, sec, msec);
}
#endregion Resolve
/// <summary>
/// Resolve must be called before using this property.
/// </summary>
public DateTime Value { get; private set; }
}
}