none
Получить рандомный промежуток времени. RRS feed

  • Вопрос

  • Казалось бы, тривиальная задача, нужно получить рандомный промежуток времени заданный в часах с точностью до минуты.

    Написал вот такой код:

    private static long MinutToTick(int hour)
        {
          return hour * new TimeSpan(0,1,0).Ticks;
        }
        private static TimeSpan GetNewPeriod(int minHour, int maxHour)
        {
          Random rand = new Random();
          int minMinut = minHour * 60;
          int maxMinut = maxHour * 60;
          int randomMinut = rand.Next(minMinut, maxMinut);
          TimeSpan result = new TimeSpan(MinutToTick(randomMinut));
          return result;
    
        }
    

    Суть в следующем. Так как класс Random понимает только int, то приходится работать с int, а рандомный результат уже переделывать в long путем конвертации из секунд в такты для конструктора TimeSpan.

    Так вот этот код регулярно выдает промежутки, которые меньше заданного. Например в цикле из 100 проб в промежутке от 5 до 27 часов он регулярно выдает промежуток до часа. Не могу понять, что происходит.

    Кстати, может кто знает красивый способ для решения данной задачи?

    • Перемещено Tagore Bandlamudi 1 октября 2010 г. 21:09 MSDN Forums consolidation (От:Visual C#)
    21 сентября 2010 г. 19:14

Ответы

  • неправильно при каждом вызове создавать новый объект Random, последовательность чисел которую он выдает зависит от текущего времени, которое при частом вызове функции не успевает обновляться, он выдает одинаковые последовательности, лучше создать один объект статический и использовать его во всей программе.

     static Random rand = new Random();
     private static long MinutToTick(int hour)
     {
      return hour * new TimeSpan(0, 1, 0).Ticks;
     }
    
     private static TimeSpan GetNewPeriod(int minHour, int maxHour)
     {
    
      int minMinut = minHour * 60;
      int maxMinut = maxHour * 60;
      int randomMinut = rand.Next(minMinut, maxMinut);
      TimeSpan result = new TimeSpan(MinutToTick(randomMinut));
      return result;
    
     }
    

     

    Теперь мой красивый способ

    static Random rand = new Random();
     
    static TimeSpan GetNewPeriod(double hourMin, double hourMax)
     {
      //Случайное число в диапазоне [hourMin, hourMax]
      double dHours = hourMin + rand.NextDouble()*(hourMax - hourMin);
      return TimeSpan.FromHours(dHours);
     }
    
    • Помечено в качестве ответа I.Vorontsov 22 сентября 2010 г. 5:40
    21 сентября 2010 г. 20:18

Все ответы

  • неправильно при каждом вызове создавать новый объект Random, последовательность чисел которую он выдает зависит от текущего времени, которое при частом вызове функции не успевает обновляться, он выдает одинаковые последовательности, лучше создать один объект статический и использовать его во всей программе.

     static Random rand = new Random();
     private static long MinutToTick(int hour)
     {
      return hour * new TimeSpan(0, 1, 0).Ticks;
     }
    
     private static TimeSpan GetNewPeriod(int minHour, int maxHour)
     {
    
      int minMinut = minHour * 60;
      int maxMinut = maxHour * 60;
      int randomMinut = rand.Next(minMinut, maxMinut);
      TimeSpan result = new TimeSpan(MinutToTick(randomMinut));
      return result;
    
     }
    

     

    Теперь мой красивый способ

    static Random rand = new Random();
     
    static TimeSpan GetNewPeriod(double hourMin, double hourMax)
     {
      //Случайное число в диапазоне [hourMin, hourMax]
      double dHours = hourMin + rand.NextDouble()*(hourMax - hourMin);
      return TimeSpan.FromHours(dHours);
     }
    
    • Помечено в качестве ответа I.Vorontsov 22 сентября 2010 г. 5:40
    21 сентября 2010 г. 20:18
  • Что бы не было проблем с созданием новых Random, лучше приделать метод расширения

    static class RandomHelper
    {
     public static TimeSpan NextMinutePeriod(this Random _this, int minHour, int maxHour)
     {
     return new TimeSpan(0, _this.Next(minHour * 60, maxHour * 60), 0);
     }
    }
    

     

    Пример использования

    static void Main(string[] args)
    {
     Random rand = new Random();
     for (int i = 0; i < 50; i++) Console.WriteLine("" + rand.NextMinutePeriod(5, 27));
    }
    
    21 сентября 2010 г. 20:31
  • Что бы не было проблем с созданием новых Random, лучше приделать метод расширения

    static class RandomHelper
    
    {
    
     public static TimeSpan NextMinutePeriod(this Random _this, int minHour, int maxHour)
    
     {
    
     return new TimeSpan(0, _this.Next(minHour * 60, maxHour * 60), 0);
    
     }
    
    }
    
    

     

    Пример использования

    static void Main(string[] args)
    
    {
    
     Random rand = new Random();
    
     for (int i = 0; i < 50; i++) Console.WriteLine("" + rand.NextMinutePeriod(5, 27));
    
    }
    
    

    Причем здесь метод расширения? Метод расширения - это обычный статический метод с контекстным параметром. Какие проблемы он может решить?
    21 сентября 2010 г. 20:56
  • Метод расширения - это обычный статический метод с контекстным параметром. Какие проблемы он может решить?

    Что бы не было неявного создания Random при каждом вызове метод. Так он создается явно в пользовательском коде и тут уже надо сильно сглупить что бы заново его пересоздавать. Плюс при это весь код не разбрасывается по файлу, а сконцентрирован в одном месте.
    21 сентября 2010 г. 21:10
  • Метод расширения - это обычный статический метод с контекстным параметром. Какие проблемы он может решить?

    Что бы не было неявного создания Random при каждом вызове метод. Так он создается явно в пользовательском коде и тут уже надо сильно сглупить что бы заново его пересоздавать. Плюс при это весь код не разбрасывается по файлу, а сконцентрирован в одном месте.


    В твоем примере объект Random является локальным для Main, на самом деле это не освобождает от ошибки в таком случае:

       for (int i = 0; i < 10000; i++)
       {
        var value = new Random().NextInterval(min, max)
       }
    
    поэтому всё таки в случае с Random взять за правило  иметь один статический объект
    21 сентября 2010 г. 21:29