using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using DateTimeTests;
namespace RandomArray
{
public static class Program
{
public static bool CalculateMilliSecOverflow(MTimeSpan ts)
{
// [ts.Milliseconds.Wrap, val.Overflow_ms.True]
return ts.Milliseconds == MTimeSpan.TimeCategory.Wrap;
}
public static bool CalculateSecOverflow(MDateTime dt, MTimeSpan ts, MValidate val)
{
// dt.Second.{*} * [ts.Seconds.Wrap]
// + [dt.Second.Max, val.Overflow_ms] * ts.Seconds.{*}
return ts.Seconds == MTimeSpan.TimeCategory.Wrap ||
(dt.Second == MDateTime.TimeCategory.Max && val.Overflow_ms);
}
public static bool CalculateMinuteOverflow(MDateTime dt, MTimeSpan ts, MValidate val)
{
// dt.Minute.{*} * [ts.Minutes.Wrap]
// + [dt.Minute.Max, val.Overflow_sec] * ts.Minutes.{*}
return ts.Minutes == MTimeSpan.TimeCategory.Wrap ||
(dt.Minute == MDateTime.TimeCategory.Max && val.Overflow_sec);
}
public static bool CalculateHourOverflow(MDateTime dt, MTimeSpan ts, MValidate val)
{
// dt.Hour.{*} * [ts.Hours.Wrap]
// + [dt.Hour.Max, val.Overflow_min] * ts.Hours.{*}
return ts.Hours == MTimeSpan.TimeCategory.Wrap ||
(dt.Hour == MDateTime.TimeCategory.Max && val.Overflow_min);
}
public static bool CalculateDayOverflowOnCommonYear(MDateTime dt, MTimeSpan ts, MValidate val)
{
// [dt.Day.SecondLast, val.Overflow_hour.True ] * !ts.Days.{Zero, Year}
// + [dt.Day.Last, val.Overflow_hour.False] * !ts.Days.{Zero, Year}
// + [dt.Day.Last, val.Overflow_hour.True ] * ts.Days.{*}
if (dt.Day == MDateTime.DayCategory.SecondLast && val.Overflow_hour)
{
return !(ts.Days == MTimeSpan.DayCategory.Zero || ts.Days == MTimeSpan.DayCategory.Year);
}
if (dt.Day == MDateTime.DayCategory.Last)
{
return val.Overflow_hour || !(ts.Days == MTimeSpan.DayCategory.Zero || ts.Days == MTimeSpan.DayCategory.Year);
}
return false;
}
public static bool CalculateDayOverflowOnLeapYear(MDateTime dt, MTimeSpan ts, MValidate val)
{
// dt.(Month.{Feb} * Year.{LeapYear, LeapCentury})
// * (
// val.Overflow_hour.{*} * {
// [dt.Day.Last, ts.Days.Year],
// [dt.Day.SecondLast, ts.Days.YearAndOneDay]
// }
// + [val.Overflow_hour.True, dt.Day.SecondLast, ts.Days.Year]
// )
if (dt.Month != MDateTime.MonthCategory.Feb) return false;
if (dt.Year != MDateTime.YearCategory.LeapYear && dt.Year != MDateTime.YearCategory.LeapCentury) return false;
if (dt.Day == MDateTime.DayCategory.Last && ts.Days == MTimeSpan.DayCategory.Year) return true;
if (dt.Day == MDateTime.DayCategory.SecondLast && ts.Days == MTimeSpan.DayCategory.YearAndOneDay) return true;
if (dt.Day == MDateTime.DayCategory.SecondLast && ts.Days == MTimeSpan.DayCategory.Year && val.Overflow_hour) return true;
return false;
}
public static bool CalculateMonthOverflow(MDateTime dt, MTimeSpan ts, MValidate val)
{
// # Overflow condtions for Dec 30
// [dt.Month.Dec, dt.Day.SecondLast, val.Overflow_day.True] * !ts.Days.{Zero, Year}
// # Overflow condtions for Dec 31
// + [dt.Month.Dec, dt.Day.Last]
// * ( [val.Overflow_day.False] * !ts.Days.{Zero, Year}
// + [val.Overflow_day.True ] * ts.Days.{*})
if (dt.Month != MDateTime.MonthCategory.Dec) return false;
if (dt.Day == MDateTime.DayCategory.SecondLast)
{
return val.Overflow_day && !(ts.Days == MTimeSpan.DayCategory.Zero || ts.Days == MTimeSpan.DayCategory.Year);
}
else if (dt.Day == MDateTime.DayCategory.Last)
{
return val.Overflow_day || !(ts.Days == MTimeSpan.DayCategory.Zero || ts.Days == MTimeSpan.DayCategory.Year);
}
return false;
}
public static bool CalculateYearOverflow(MDateTime dt, MTimeSpan ts, MValidate val)
{
// [dt.Year.Max, val.Overflow_mon.False] * !ts.Days.{Zero, One}
// + [dt.Year.Max, val.Overflow_mon.True ] * ts.Days.{*}
if (dt.Year != MDateTime.YearCategory.Max) return false;
return val.Overflow_mon || !(ts.Days == MTimeSpan.DayCategory.Zero || ts.Days == MTimeSpan.DayCategory.One);
}
public static bool CheckConstraints(MDateTime dt, MTimeSpan ts)
{
// # Strength-2 constraints
// { [dt.Millisecond.Min, ts.Milliseconds.Wrap] },
// # Strength-3 constraints
// { [dt.Second.Min, ts.Milliseconds.NoWrap, ts.Seconds.Wrap],
// [dt.Minute.Min, ts.Seconds.NoWrap, ts.Minutes.Wrap],
// [dt.Hour.Min, ts.Minutes.NoWrap, ts.Hours.Wrap]
// })
if (dt.Millisecond == MDateTime.TimeCategory.Min && ts.Milliseconds == MTimeSpan.TimeCategory.Wrap) return false;
if (dt.Second == MDateTime.TimeCategory.Min && ts.Milliseconds == MTimeSpan.TimeCategory.NoWrap && ts.Seconds == MTimeSpan.TimeCategory.Wrap) return false;
if (dt.Minute == MDateTime.TimeCategory.Min && ts.Seconds == MTimeSpan.TimeCategory.NoWrap && ts.Minutes == MTimeSpan.TimeCategory.Wrap) return false;
if (dt.Hour == MDateTime.TimeCategory.Min && ts.Minutes == MTimeSpan.TimeCategory.NoWrap && ts.Hours == MTimeSpan.TimeCategory.Wrap) return false;
return true;
}
static void Main(string[] args)
{
const int trials = 1000;
int countRejected = 0;
Randomizer randomizer = new Randomizer();
for (int i = 0; i != trials; ++i)
{
MDateTime dt = new MDateTime();
MTimeSpan ts = new MTimeSpan();
randomizer.RandomizeAllEnums(dt);
randomizer.RandomizeAllEnums(ts);
if (CheckConstraints(dt, ts))
{
MValidate val = new MValidate();
val.Overflow_ms = CalculateMilliSecOverflow(ts);
val.Overflow_sec = CalculateSecOverflow(dt, ts, val);
val.Overflow_min = CalculateMinuteOverflow(dt, ts, val);
val.Overflow_hour = CalculateHourOverflow(dt, ts, val);
val.Overflow_day = CalculateDayOverflowOnCommonYear(dt, ts, val) || CalculateDayOverflowOnLeapYear(dt, ts, val);
val.Overflow_mon = CalculateMonthOverflow(dt, ts, val);
val.Overflow_year = CalculateYearOverflow(dt, ts, val);
DateTimeTests.DateTimeTests.AddTimeSpan(dt, ts, val);
}
else
{
++countRejected;
--i;
}
}
Console.WriteLine("{0} tests executed successfully", trials);
Console.WriteLine("Created {0} random samples (with {1} samples rejected due to constraints)", trials + countRejected, countRejected);
}
}
}