ฉันกำลังมองหารหัส C # ที่สั้นและทันสมัยเพื่อสร้างวันที่สุ่มระหว่างวันที่ 1 มกราคม 1995 และวันที่ปัจจุบัน
ฉันคิดว่าวิธีการแก้ปัญหาที่ใช้ Enumerable บางช่วงอาจทำให้รวบรัดมากขึ้น
ฉันกำลังมองหารหัส C # ที่สั้นและทันสมัยเพื่อสร้างวันที่สุ่มระหว่างวันที่ 1 มกราคม 1995 และวันที่ปัจจุบัน
ฉันคิดว่าวิธีการแก้ปัญหาที่ใช้ Enumerable บางช่วงอาจทำให้รวบรัดมากขึ้น
คำตอบ:
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));
}
เพื่อประสิทธิภาพที่ดีขึ้นหากเรียกสิ่งนี้ซ้ำ ๆ ให้สร้างตัวแปรstart
และgen
(และอาจรวมถึงrange
) นอกฟังก์ชัน
นี่คือการตอบสนองเล็กน้อยต่อความคิดเห็นของโจเอลเกี่ยวกับการสร้างเวอร์ชั่นที่ได้รับการปรับปรุงให้ดีขึ้นเล็กน้อย แทนที่จะส่งคืนวันที่แบบสุ่มโดยตรงทำไมไม่ส่งคืนฟังก์ชันตัวสร้างซึ่งสามารถเรียกซ้ำ ๆ เพื่อสร้างวันที่แบบสุ่ม
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();
จากนั้นคุณเรียกมันว่าเพื่อรับวันที่สุ่ม: var randomDate = getRandomDate();
ใจที่คุณต้องนำ getRandomDate กลับมาใช้ใหม่เพื่อให้สิ่งนี้มีประโยชน์มากกว่าคำตอบของ Joel
ฉันได้รับ @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));
}
}
และตัวอย่างวิธีใช้เพื่อเขียน DateTimes แบบสุ่ม 100 รายการไปยังคอนโซล:
RandomDateTime date = new RandomDateTime();
for (int i = 0; i < 100; i++)
{
Console.WriteLine(date.Next());
}
range = (int)(DateTime.Today - start).TotalSeconds;
return start.AddSeconds(gen.Next(range));
ถ้าคุณจะนำเสนอการเพิ่มประสิทธิภาพทางเลือกเราสามารถไปทำซ้ำได้:
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;
}
เริ่มต้นด้วยวัตถุวันที่คงที่ (1 มกราคม 1995) และเพิ่มจำนวนวันแบบสุ่มด้วย 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);
}