Wednesday, September 12, 2007

How to get a random date in C#

I looked everywhere for a sample on generating random dates in C# but could find any so I wrote mine.


private static DateTime getRandomDate(Random rand,
DateTime minDate, DateTime maxDate)
{
int totalDays = (int)DateTimeUtil.DateDiff(
DateInterval.Day , minDate, maxDate);
int randomDays = rand.Next(0,totalDays);
return minDate.AddDays(randomDays);

}


This function uses the DateTime utility class below which I found somewhere on the web.

public enum DateInterval
{
Day,
DayOfYear,
Hour,
Minute,
Month,
Quarter,
Second,
Weekday,
WeekOfYear,
Year
}

///

public sealed class DateTimeUtil
{

#region DateDiff Methods

public static long DateDiff(DateInterval interval,
DateTime dt1, DateTime dt2)
{

return DateDiff(interval, dt1, dt2, System.Globalization
.DateTimeFormatInfo.CurrentInfo.FirstDayOfWeek);

}

private static int GetQuarter(int nMonth)
{
if (nMonth <= 3)
return 1;
if (nMonth <= 6)
return 2;
if (nMonth <= 9)
return 3;
return 4;
}

public static long DateDiff(DateInterval interval,
DateTime dt1, DateTime dt2, DayOfWeek eFirstDayOfWeek)
{

if (interval == DateInterval.Year)

return dt2.Year - dt1.Year;

if (interval == DateInterval.Month)

return (dt2.Month - dt1.Month) +
(12 * (dt2.Year - dt1.Year));

TimeSpan ts = dt2 - dt1;

if (interval == DateInterval.Day ||
interval == DateInterval.DayOfYear)
return Round(ts.TotalDays);

if (interval == DateInterval.Hour)
return Round(ts.TotalHours);

if (interval == DateInterval.Minute)
return Round(ts.TotalMinutes);

if (interval == DateInterval.Second)

return Round(ts.TotalSeconds);

if (interval == DateInterval.Weekday)
{
return Round(ts.TotalDays / 7.0);
}

if (interval == DateInterval.WeekOfYear)
{
while (dt2.DayOfWeek != eFirstDayOfWeek)
dt2 = dt2.AddDays(-1);
while (dt1.DayOfWeek != eFirstDayOfWeek)
dt1 = dt1.AddDays(-1);
ts = dt2 - dt1;
return Round(ts.TotalDays / 7.0);
}

if (interval == DateInterval.Quarter)
{
double d1Quarter = GetQuarter(dt1.Month);
double d2Quarter = GetQuarter(dt2.Month);
double d1 = d2Quarter - d1Quarter;
double d2 = (4 * (dt2.Year - dt1.Year));
return Round(d1 + d2);
}
return 0;
}

private static long Round(double dVal)
{
if (dVal >= 0)
return (long)Math.Floor(dVal);
return (long)Math.Ceiling(dVal);
}
#endregion
}

3 comments:

James said...

I used your random date generator to test my list sorting by date string.

You saved me a few minutes, so thanks!

I made an overload for it to, so I could just use it for general testing where the date didn't matter too much.

I encapsulated the 'getRandomDate' into the class too, so you don't have to bother with creating an instance of 'Random'

like this:


public sealed class DateTimeUtil
{
static Random rand = new Random();
public static DateTime GetRandomDate()
{
DateTime minDate = new DateTime(1968, 9, 5);
DateTime maxDate = new DateTime(2008, 6, 1);
return (GetRandomDate(minDate, maxDate));
}

public static DateTime GetRandomDate(DateTime minDate, DateTime maxDate)
{
int totalDays = (int)DateTimeUtil.DateDiff(DateInterval.Day, minDate, maxDate);
int randomDays = rand.Next(0, totalDays);
return minDate.AddDays(randomDays);
}
etc..



Happy programming!

James

buy wow gold said...

When Wow Gold wolf finally found the wow gold cheap hole in the chimney he crawled cheap wow gold down and KERSPLASH right into that kettle of water and that was cheapest wow gold the end of his troubles with the big bad wolf.
game4power.
The next day the Buy Wow Goldlittle pig invited hisbuy gold wow mother over . She said "You see it is just as mygamegoldI told you. The way to get along in the world is to do world of warcraft gold things as well as you can." Fortunately for that little pig, he buy cheap wow gold learned that lesson. And he just k4gold lived happily ever after!.

Jan said...

what about using TimeSpan instead?

int totalDays = ((TimeSpan)(maxDate - minDate)).Days;