Szukam jakiegoś zwięzłego, nowoczesnego kodu C # do generowania losowej daty między 1 stycznia 1995 a bieżącą datą.
Myślę, że jakieś rozwiązanie wykorzystujące Enumerable.Range może w jakiś sposób uczynić to bardziej zwięzłym.
Szukam jakiegoś zwięzłego, nowoczesnego kodu C # do generowania losowej daty między 1 stycznia 1995 a bieżącą datą.
Myślę, że jakieś rozwiązanie wykorzystujące Enumerable.Range może w jakiś sposób uczynić to bardziej zwięzłym.
Odpowiedzi:
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));
}
Aby uzyskać lepszą wydajność, jeśli będzie to wywoływane wielokrotnie, utwórz zmienne start
and gen
(a może nawet range
) poza funkcją.
Jest to niewielka odpowiedź na komentarz Joela dotyczący stworzenia nieco bardziej zoptymalizowanej wersji. Zamiast zwracać losową datę bezpośrednio, dlaczego nie zwrócić funkcji generatora, którą można wielokrotnie wywoływać, aby utworzyć losową datę.
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));
}
for (int i = 0; i < 100; i++) { array[i].DateProp = RandomDayFunc()(); }
var getRandomDate = RandomDayFunc();
następnie dzwonisz do niej, aby uzyskać losowe daty: var randomDate = getRandomDate();
Pamiętaj, że musisz ponownie użyć getRandomDate, aby było to bardziej przydatne niż odpowiedź Joela.
Wziąłem odpowiedź @Joel Coehoorn i wprowadziłem zmiany, które doradził - wyrzuciłem zmienną z metody i umieściłem wszystko w klasie. A teraz czas też jest losowy. Oto wynik.
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));
}
}
I przykład, jak użyć do zapisania 100 losowych DateTimes na konsoli:
RandomDateTime date = new RandomDateTime();
for (int i = 0; i < 100; i++)
{
Console.WriteLine(date.Next());
}
range = (int)(DateTime.Today - start).TotalSeconds;
i return start.AddSeconds(gen.Next(range));
.
Cóż, jeśli chcesz przedstawić alternatywną optymalizację, możemy również wybrać iterator:
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));
}
możesz tego użyć w ten sposób:
int i=0;
foreach(DateTime dt in RandomDay())
{
Console.WriteLine(dt);
if (++i == 10)
break;
}
Zacznij od obiektu z ustaloną datą (1 stycznia 1995) i dodaj losową liczbę dni za pomocą AddDays (oczywiście, zwróć uwagę, aby nie przekroczyć bieżącej daty).
Jestem trochę za późno w grze, ale oto jedno rozwiązanie, które działa dobrze:
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;
}
}
}
Mała metoda, która zwraca losową datę w postaci ciągu na podstawie kilku prostych parametrów wejściowych. Zbudowany na podstawie odchyleń od powyższych odpowiedzi:
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);
}