1 Ocak 1995 ve şimdiki tarih arasında rastgele bir tarih oluşturmak için bazı özlü, modern C # kodu arıyorum.
Enumerable kullanan bir çözüm düşünüyorum.Range bir şekilde bu daha özlü olabilir.
1 Ocak 1995 ve şimdiki tarih arasında rastgele bir tarih oluşturmak için bazı özlü, modern C # kodu arıyorum.
Enumerable kullanan bir çözüm düşünüyorum.Range bir şekilde bu daha özlü olabilir.
Yanıtlar:
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));
}
Eğer tekrar tekrar çağrılırsa daha iyi performans için start
ve gen
(ve hatta belki range
) değişkenleri fonksiyonun dışında oluşturun.
Bu, Joel'in çok daha optimize edilmiş bir sürüm yapma hakkındaki yorumuna hafif bir yanıt veriyor. Rastgele bir tarihi doğrudan döndürmek yerine, neden rastgele bir tarih oluşturmak için tekrar tekrar çağrılabilen bir jeneratör işlevi döndürmüyorsunuz?
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();
o zaman rastgele tarihler almak için onu çağırırsınız: Bunun var randomDate = getRandomDate();
Joel'in cevabından daha yararlı olması için getRandomDate'i tekrar kullanmanız gerektiğini unutmayın.
@Joel Coehoorn'un cevabını aldım ve önerdiği değişiklikleri yaptım - değişkeni metodun dışına çık ve hepsini sınıfa koydum. Artı şimdi zaman da rastgele. İşte sonuç.
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));
}
}
Konsolda 100 rastgele DateTimes yazmak için nasıl kullanılacağına örnek:
RandomDateTime date = new RandomDateTime();
for (int i = 0; i < 100; i++)
{
Console.WriteLine(date.Next());
}
range = (int)(DateTime.Today - start).TotalSeconds;
ve return start.AddSeconds(gen.Next(range));
.
Alternatif optimizasyon sunacaksanız, bir yineleyici de yapabiliriz:
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));
}
şöyle kullanabilirsiniz:
int i=0;
foreach(DateTime dt in RandomDay())
{
Console.WriteLine(dt);
if (++i == 10)
break;
}
Sabit bir tarih nesnesiyle başlayın (1 Ocak 1995) ve AddDays ile rastgele sayıda gün ekleyin (açıkça, geçerli tarihi geçmemeye dikkat edin).
Oyuna biraz geç kaldım, ama burada iyi çalışan bir çözüm var:
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;
}
}
}
Bazı basit giriş parametrelerine dayanarak rastgele bir tarih dize olarak döndüren küçük yöntem. Yukarıdaki cevaplardan farklı olarak oluşturulmuştur:
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);
}