[C#] C #의 임의 날짜

1995 년 1 월 1 일과 현재 날짜 사이에 임의의 날짜를 생성하는 간결하고 현대적인 C # 코드를 찾고 있습니다.

Enumerable을 사용하는 솔루션을 생각하고 있습니다 .Range는 어떻게 든 간결하게 만들 수 있습니다.



답변

private Random gen = new Random();
DateTime RandomDay()
{
    DateTime start = new DateTime(1995, 1, 1);
    int range = (DateTime.Today - start).Days;
    return start.AddDays(gen.Next(range));
}

반복적으로 호출 될 경우 성능을 향상 시키려면 함수 외부startand gen(및 가능하면 range) 변수를 작성하십시오 .


답변

이것은 매우 최적화 된 버전을 만드는 것에 대한 Joel의 의견에 대한 약간의 대답입니다. 임의의 날짜를 직접 반환하는 대신 임의의 날짜를 만들기 위해 반복적으로 호출 할 수있는 생성기 함수를 반환하지 않는 것이 좋습니다.

Func<DateTime> RandomDayFunc()
{
    DateTime start = new DateTime(1995, 1, 1);
    Random gen = new Random();
    int range = ((TimeSpan)(DateTime.Today - start)).Days;
    return () => start.AddDays(gen.Next(range));
}


답변

@Joel Coehoorn의 답변을 취하고 조언을 변경했습니다. 변수를 메소드에서 꺼내고 클래스에 모두 넣습니다. 또한 이제 시간도 임의적입니다. 결과는 다음과 같습니다.

class RandomDateTime
{
    DateTime start;
    Random gen;
    int range;

    public RandomDateTime()
    {
        start = new DateTime(1995, 1, 1);
        gen = new Random();
        range = (DateTime.Today - start).Days;
    }

    public DateTime Next()
    {
        return start.AddDays(gen.Next(range)).AddHours(gen.Next(0,24)).AddMinutes(gen.Next(0,60)).AddSeconds(gen.Next(0,60));
    }
}

그리고 콘솔에 100 개의 임의의 DateTime을 쓰는 데 사용하는 방법의 예 :

RandomDateTime date = new RandomDateTime();
for (int i = 0; i < 100; i++)
{
    Console.WriteLine(date.Next());
}


답변

대체 최적화를 제시하려면 반복자를 사용할 수도 있습니다.

 static IEnumerable<DateTime> RandomDay()
 {
    DateTime start = new DateTime(1995, 1, 1);
    Random gen = new Random();
    int range = ((TimeSpan)(DateTime.Today - start)).Days;
    while (true)
        yield return  start.AddDays(gen.Next(range));
}

다음과 같이 사용할 수 있습니다.

int i=0;
foreach(DateTime dt in RandomDay())
{
    Console.WriteLine(dt);
    if (++i == 10)
        break;
}


답변

고정 날짜 개체 (1995 년 1 월 1 일)로 시작하고 AddDays를 사용하여 임의의 일 수를 추가하십시오 (분명히 현재 날짜를 초과하지 않도록주의하십시오).


답변

나는 게임에 조금 늦었지만 여기에 잘 작동하는 솔루션이 있습니다.

    void Main()
    {
        var dateResult = GetRandomDates(new DateTime(1995, 1, 1), DateTime.UtcNow, 100);
        foreach (var r in dateResult)
            Console.WriteLine(r);
    }

    public static IList<DateTime> GetRandomDates(DateTime startDate, DateTime maxDate, int range)
    {
        var randomResult = GetRandomNumbers(range).ToArray();

        var calculationValue = maxDate.Subtract(startDate).TotalMinutes / int.MaxValue;
        var dateResults = randomResult.Select(s => startDate.AddMinutes(s * calculationValue)).ToList();
        return dateResults;
    }

    public static IEnumerable<int> GetRandomNumbers(int size)
    {
        var data = new byte[4];
        using (var rng = new System.Security.Cryptography.RNGCryptoServiceProvider(data))
        {
            for (int i = 0; i < size; i++)
            {
                rng.GetBytes(data);

                var value = BitConverter.ToInt32(data, 0);
                yield return value < 0 ? value * -1 : value;
            }
        }
    }


답변

간단한 입력 매개 변수를 기반으로 임의의 날짜를 문자열로 반환하는 작은 메서드입니다. 위 답변의 변형을 기반으로 작성되었습니다.

public string RandomDate(int startYear = 1960, string outputDateFormat = "yyyy-MM-dd")
{
   DateTime start = new DateTime(startYear, 1, 1);
   Random gen = new Random(Guid.NewGuid().GetHashCode());
   int range = (DateTime.Today - start).Days;
   return start.AddDays(gen.Next(range)).ToString(outputDateFormat);
}