सी # में रैंडम तारीख


141

मैं 1 जनवरी 1995 और वर्तमान तिथि के बीच एक यादृच्छिक तारीख उत्पन्न करने के लिए कुछ सफल, आधुनिक सी # कोड की तलाश कर रहा हूं।

मैं कुछ समाधान सोच रहा हूं जो Enumerable का उपयोग करता है। किसी भी तरह यह अधिक सफल हो सकता है।


श्रेणी के बीच रैंडम डेटटाइम में उत्तर - नहीं एकीकृत आउटपुट में सहायक विधि है जिसमें से / आज तक पैरामीटर हैं
माइकल फ्रीजिम

जवाबों:


241
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) चर बाहर समारोह की।


1
यादृच्छिक केवल छद्म यादृच्छिक है। अगर आपको सही मायने में यादृच्छिक की जरूरत है, तो System.Security.Cryptography नाम स्थान से RNGCryptoServiceProvider का उपयोग करने का प्रयास करें।
tvanfosson

धन्यवाद tvanfosson इस समस्या के लिए छद्म यादृच्छिक पर्याप्त है।
जूडाह गैब्रियल हिमांगो

5
वास्तव में, रैंडम भी विशेष रूप से छद्म यादृच्छिक नहीं है जब तक कि आप उदाहरण को कुछ समय के लिए इधर-उधर न रखें और इससे मान प्राप्त न करें।
डेविड मिशेल

2
यही कारण है कि यह उत्पादन कोड के बजाय केवल एक नमूना है।
जोएल कोएहॉर्न

1
हां, यह मेरे लिए काम करता है; मेरी वास्तविक दुनिया कोड विधि के बाहर ही यादृच्छिक उदाहरण होगा।
जुडाह गेब्रियल हिमंगो

25

यह थोड़ा और अधिक अनुकूलित संस्करण बनाने के बारे में जोएल की टिप्पणी की थोड़ी प्रतिक्रिया में है। सीधे रैंडम डेट वापस करने के बजाय, क्यों न एक जेनरेटर फंक्शन लौटाया जाए जिसे रैंडम डेट बनाने के लिए बार-बार कॉल किया जा सके।

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));
}

क्या आप बता सकते हैं कि यह कैसे फायदेमंद है? इसके बजाय कक्षा के सदस्य शुरू, जीन और रेंज नहीं कर सकते हैं
मार्क ए। निकोलोसी

वे कर सकते थे और इस मामले में वे हैं। हुड के तहत यह एक लेक्सिकल क्लोजर उत्पन्न करेगा जो सदस्यों के रूप में प्रारंभ, जीन और रेंज युक्त एक clrass है। यह सिर्फ और अधिक संक्षिप्त है।
JaredPar

अच्छा कार्य, मैं बस उम्मीद कर रहा हूं कि कोई भी इसका उपयोग करने वाला नहीं है:for (int i = 0; i < 100; i++) { array[i].DateProp = RandomDayFunc()(); }
एदिअकापी

2
इस फ़ंक्शन का उपयोग कैसे किया जाता है, क्या कोई कृपया समझा सकता है? मेरा मतलब है कि मैं इसे कैसे कह सकता हूं?
बुरक करकुस

2
@ BurakKarakuş: आपको पहले एक फैक्ट्री मिलती है: var getRandomDate = RandomDayFunc();फिर आप इसे रैंडम var randomDate = getRandomDate();डेट्स पाने के लिए कहते हैं: माइंड कि आपको इसे पाने के लिए फिर से इस्तेमाल करना होगा ताकि जोएल के जवाब से ज्यादा उपयोगी हो।
गूर

8

मैंने @ जोएल कोएहॉर्न उत्तर लिया है और उन परिवर्तनों को जो उन्होंने सलाह दी है - चर को विधि से बाहर रखा और सभी को कक्षा में रखा। इसके अलावा अब समय भी यादृच्छिक है। यहाँ परिणाम है।

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 यादृच्छिक DateTimes लिखने के लिए उपयोग करने के लिए:

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

आप दो बार रैंडम () क्यों बनाते हैं? एक बार कक्षा चर जीन घोषणा में और दूसरी बार सी-टॉर में?
पिक्सेल

हाँ, एक बार काफी है। मैंने ठीक कर दिया।
6

1
यह केवल चार सेकंड की एक ही यादृच्छिक संख्या उत्पन्न करने और अपनी आरंभ तिथि में जोड़ने के लिए लगभग चार गुना तेज़ है: range = (int)(DateTime.Today - start).TotalSeconds;और return start.AddSeconds(gen.Next(range));
ज्यूरी

5

यदि आप वर्तमान वैकल्पिक अनुकूलन को स्वीकार करते हैं, तो हम एक पुनरावृत्तिकर्ता के लिए भी जा सकते हैं:

 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
इट्रेटर बनाम एक जनरेटर फ़ंक्शन के बीच विचार करने के लिए एक बात यह है कि इटरेटर समाधान एक आइडीसॉफ़िकल मूल्य का उत्पादन करेगा। यह कॉल करने वाले को जीसी में अंतिम रूप से रहने वाले की कीमत चुकाने या भुगतान करने के लिए मजबूर करता है। जनरेटर को कोई निपटान की आवश्यकता नहीं है
JaredPar

2
@JaredPar, यह बिल्कुल सही नहीं है। सिर्फ इसलिए कि एक प्रकार का आईडेसपॉली लागू होने का मतलब यह नहीं है कि यह अंतिम रूप देने योग्य है।
ड्रू नोक

3

एक निश्चित दिनांक ऑब्जेक्ट (1 जनवरी, 1995) से शुरू करें, और AddDays के साथ दिनों की एक यादृच्छिक संख्या जोड़ें (मोटे तौर पर, वर्तमान तिथि को पार न करने पर ध्यान दें)।


धन्यवाद फ्रियोल। मैं पूछने जा रहा था कि कैसे यादृच्छिक में पारित संख्या को सीमित करें। जोएल ने कोड नमूने के साथ एक उदाहरण पोस्ट किया है, इसलिए मैं जवाब के रूप में उनकी प्रतिक्रिया को चिह्नित करूंगा।
जूडाह गैब्रियल हिमांगो

0

मुझे खेल में थोड़ी देर हो गई है, लेकिन यहाँ एक समाधान है जो ठीक काम करता है:

    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;
            }
        }
    }

0

छोटी विधि जो कुछ सरल इनपुट मापदंडों के आधार पर एक यादृच्छिक तारीख को स्ट्रिंग के रूप में लौटाती है। उपरोक्त उत्तरों से भिन्नताओं के आधार पर निर्मित:

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);
}
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.