Random DateTime между диапазоном - не унифицированный вывод

Я реализовал ниже RandomDate, но всегда сохраняю значения закрытыми для "От", я, вероятно, что-то пропустил здесь.

public static DateTime GetRandomDate(DateTime from, DateTime to)
    {
        var range = new TimeSpan(to.Ticks - from.Ticks);

        var rnd = new Random();

        var randTimeSpan = new TimeSpan((long)(range.TotalSeconds - rnd.Next(0, (int)range.TotalSeconds))); 

        return from + randTimeSpan;
    }

Ответ 1

Вы можете изменить на:

static readonly Random rnd = new Random();
public static DateTime GetRandomDate(DateTime from, DateTime to)
{
    var range = to - from;

    var randTimeSpan = new TimeSpan((long)(rnd.NextDouble() * range.Ticks)); 

    return from + randTimeSpan;
}

Объяснение: Я использовал NextDouble(), потому что он дает число между 0.0 и 1.0. Ваше возвращаемое значение не будет целым числом секунд в моем решении. И я переместил rnd в поле класса /struct. Поскольку лучше всего использовать один экземпляр Random, а не создавать новый каждый раз, когда вам нужно только одно дополнительное случайное число.

Ответ 2

Проблема в том, что:

var randTimeSpan = new TimeSpan((long)(range.TotalSeconds - rnd.Next(0, (int)range.TotalSeconds)));

создает TimeSpan от TICKS, а не от SECONDS.

Вам нужно:

var randTimeSpan = TimeSpan.FromSeconds((long)(range.TotalSeconds - rnd.Next(0, (int)range.TotalSeconds)));

(Пожалуйста, проверьте также листинг - он должен быть дважды передан в FromSeconds)

Ответ 4

Исправлено ArgumentOutOfRangeException:

public static DateTime GetRandomDateTime(DateTime? min = null, DateTime? max = null)
{
    min = min ?? new DateTime(1753, 01, 01);
    max = max ?? new DateTime(9999, 12, 31);

    var range = max.Value - min.Value;
    var randomUpperBound = (Int32) range.TotalSeconds;
    if (randomUpperBound <= 0)
        randomUpperBound = Rnd.Next(1, Int32.MaxValue);

    var randTimeSpan = TimeSpan.FromSeconds((Int64) (range.TotalSeconds - Rnd.Next(0, randomUpperBound)));
    return min.Value.Add(randTimeSpan);
}

Ответ 5

Это работает для меня. Интервал дней до 28, чтобы избежать исключения с февраля.

Random r = new Random();
DateTime rDate = new DateTime(r.Next(1900, 2010), r.Next(1, 12), r.Next(1, 28));

Ответ 6

Моя идея: нам просто нужно некоторое случайное количество добавленных тиков, чтобы начать datetime, чтобы получить случайную дату между началом и концом. Поэтому мое решение не создает никаких объектов TimeSpan.

private static readonly Random random = new Random ();
private static readonly object syncLock = new object ();

public static DateTime RandomDate(DateTime from, DateTime to)
{
    lock ( syncLock )
    {
         return from.AddTicks ((long) ( random.NextDouble () * ( to.Ticks - from.Ticks ) ));
    }
 }

Ответ 7

это может помочь

public class Program
{
    public static void Main()
    {
        Console.WriteLine(GetRandomDate(new DateTime(2014, 5, 1),new DateTime(2014, 7, 1)).ToString("dd/MM/yyyy"));
    }

    static readonly Random rnd = new Random();
    public static DateTime GetRandomDate(DateTime from, DateTime to)
    {
        var range = to - from;

        var randTimeSpan = new TimeSpan((long)(rnd.NextDouble() * range.Ticks)); 

        return from + randTimeSpan;
    }

}