Saya mencari beberapa kode C # modern yang ringkas untuk menghasilkan tanggal acak antara 1 Jan 1995 dan tanggal sekarang.
Saya sedang memikirkan solusi yang memanfaatkan Enumerable. Rentang entah bagaimana dapat membuat ini lebih ringkas.
Saya mencari beberapa kode C # modern yang ringkas untuk menghasilkan tanggal acak antara 1 Jan 1995 dan tanggal sekarang.
Saya sedang memikirkan solusi yang memanfaatkan Enumerable. Rentang entah bagaimana dapat membuat ini lebih ringkas.
Jawaban:
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));
}
Untuk kinerja yang lebih baik jika ini akan dipanggil berulang kali, buat variabel start
dan gen
(dan mungkin bahkan range
) di luar fungsi.
Ini adalah tanggapan kecil atas komentar Joel tentang membuat versi yang sedikit lebih dioptimalkan. Daripada mengembalikan tanggal acak secara langsung, mengapa tidak mengembalikan fungsi generator yang bisa dipanggil berulang kali untuk membuat tanggal acak.
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();
kemudian Anda menyebutnya untuk mendapatkan tanggal acak: var randomDate = getRandomDate();
Ingatlah bahwa Anda perlu menggunakan kembali getRandomDate agar ini lebih berguna daripada jawaban Joel.
Saya telah mengambil jawaban @Joel Coehoorn dan membuat perubahan yang dia sarankan - keluarkan variabel dari metode dan taruh semuanya di kelas. Ditambah sekarang waktunya juga acak. Inilah hasilnya.
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));
}
}
Dan contoh bagaimana menggunakan untuk menulis 100 DateTimes acak ke konsol:
RandomDateTime date = new RandomDateTime();
for (int i = 0; i < 100; i++)
{
Console.WriteLine(date.Next());
}
range = (int)(DateTime.Today - start).TotalSeconds;
dan return start.AddSeconds(gen.Next(range));
.
Nah, jika Anda ingin menampilkan pengoptimalan alternatif, kami juga dapat menggunakan 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));
}
Anda bisa menggunakannya seperti ini:
int i=0;
foreach(DateTime dt in RandomDay())
{
Console.WriteLine(dt);
if (++i == 10)
break;
}
Mulailah dengan objek tanggal tetap (Jan 1, 1995), dan tambahkan jumlah hari acak dengan AddDays (jelas-jelas, perhatikan tidak melebihi tanggal saat ini).
Saya agak terlambat dalam permainan ini, tetapi berikut adalah satu solusi yang berfungsi dengan baik:
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;
}
}
}
Metode kecil yang mengembalikan tanggal acak sebagai string, berdasarkan beberapa parameter masukan sederhana. Dibangun berdasarkan variasi dari jawaban di atas:
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);
}