【问题标题】:Random Time Generator for Time Between Time NOW to 23.99 (End of the Current Day)从现在到 23.99(当天结束)之间的时间的随机时间生成器
【发布时间】:2020-07-15 05:41:18
【问题描述】:

我创建了一些代码和类来获取当前时间 (NOW) 和一天结束之间的随机小时和分钟。我的代码有效,但有时时间是错误的。

假设现在是晚上 11:30,我运行代码,我得到错误的输出,写入输出如下所示... 值必须按从现在(执行时)到当天结束的顺序排列。

有谁知道我做错了什么?

错误(小时/分钟)

  • 0:23 - 12:23 AM(次日)
  • 23:15 - 晚上 11:15

右(小时/分钟)

  • 23:15 - 晚上 11:15
  • 0:23 - 12:23 AM(次日)
public class MyHourMinuteTestClass
{
   ArrayList projects  = new ArrayList();
   TimeSpan start = DateTime.Now.TimeOfDay;
   TimeSpan s = TimeSpan.FromHours(DateTime.Now.Hour);
   TimeSpan e = TimeSpan.FromHours(23.99);
   int maxMin = (int)((e - s).TotalMinutes);

   public MyHourMinuteTestClass()
   {
   }

   public void TestValues()
   {
       // create 2 sets of values and add a new SocialTimes instance containing the hour/minute to the array list
      for(int i = 0; i < 2; i++)
      {
          int minutes = randomGen.Next(maxMin);
          TimeSpan t = start.Add(TimeSpan.FromMinutes(minutes));
          int PostTimeHour = t.Hours;
          int PostTimeMinutes = t.Minutes;
          projects.Add(new SocialTimes(NowDateStr, PostTimeHour, PostTimeMinutes));
      }

      // then I sort the projects array list
      projects.Sort(new hoursMinutesComparer());
    }
}

public class SocialTimes
{
        string DateToPostStr = "";
        public int HourToPost = 0;
        public int MinuteToPost = 0;

        public SocialTimes(string DateToPostStr, int HourToPost, int MinuteToPost)
        {
            this.DateToPostStr = DateToPostStr;
            this.HourToPost = HourToPost;
            this.MinuteToPost = MinuteToPost;
        }

        public string getDateToPostStr()
        {
            return this.DateToPostStr;
        }

        public int getHourToPost()
       {
            return this.HourToPost;
        }

        public int getMinuteToPost()
        {
            return this.MinuteToPost;
        }

        public int getHourMinuteToPost()
        {
            int sum;

            sum = HourToPost * 60 + MinuteToPost;

            return sum;
        }
 }

public class hoursMinutesComparer : IComparer
{
     int IComparer.Compare(Object xx, Object yy)
     {
         SocialTimes x = (SocialTimes)xx;
         SocialTimes y = (SocialTimes)yy;

         return x.getHourMinuteToPost().CompareTo(y.getHourMinuteToPost());
      }
 }

【问题讨论】:

  • 我可能会计算出一天还剩下多少分钟,因为这似乎是您的精确度。在该范围内选择一个随机值,将这些分钟添加到现在的时间,然后根据需要对其进行格式化。
  • 这能回答你的问题吗? Random date in C#
  • 23:15 - 11:15 PM怎么可能是对也错?
  • 试试这个:var r = new Random(); var n = DateTime.Now; var result = n.AddSeconds(r.NextDouble() * n.AddDays(1.0).Date.Subtract(n).TotalSeconds);.

标签: c# datetime time


【解决方案1】:

这是一些冗长的代码。让我们看看我能不能把它减少一点/给一个代码块你可以用来激发灵感(因为这似乎是一个家庭作业)

public class Project{
  public Guid ID { get; set;}
  public DateTime Created{ get; set; }
}

public static class ProjectFactory{
  private static Random _r = new Random();

  public static Project CreateProject(){

    DateTime midnightTomorrow = DateTime.Today.AddDays(1);
    int secTilDayEnd = (int)(midnightTomorrow - DateTime.Now).TotalSeconds; 

    return new Project(){
      ID = Guid.NewGuid(),
      Created = DateTime.Now.AddSeconds(_r.Next(secTilDayEnd))
    };
  }
}

//and to use it

List<Project> p = new List<Project>(1000);
for(int i = 0; i < 1000; i++)
  p.Add(ProjectFactory.CreateProject());

foreach(var x in p.OrderBy(proj => proj.Created))
  Console.WriteLine($"Project {x.Id} created {x.Created:HH:mm}");

让我们将随机时间存储在日期时间中;如果我们只想要时间,我们总是可以挖掘时间,但保留日期有助于保留。这也意味着我们可以只使用 C# 中内置的默认日期时间比较 - 它知道如何排序日期

我创建了一个班级,该班级的唯一工作是制造项目,其创建日期介于现在和一天结束之间的某个时间。它通过计算到一天结束的秒数并将这些秒的随机数添加到当前时间来实现这一点

然后是创建一千个项目的代码片段,按日期排序并打印出来,只显示时间

【讨论】:

  • 为什么要添加Guid ID?
  • 到 a) 显示如何添加另一个属性,b) 显示如何初始化多个属性 c) 在控制台打印输出中区分它们 - 如果在一天的最后 45 分钟运行,这是肯定的1000 个项目的列表只会在 HH:mm 上重复 d) 因为它很容易初始化为唯一值..
  • 感谢 Caius... 这些类非常干净且有意义。但是我很困惑为什么要使用一个名为midnightTomorrow 的变量。它应该只在现在和一天结束之间创建项目。你可以解释吗?此外,对于其他人,返回码有语法错误。 return new Project() { ID = Guid.NewGuid(), Created = DateTime.Now.AddSeconds(_r.Next(secTilDayEnd)) };
  • 另外,在将所有项目都添加到列表后,如何对列表 p 进行排序?我只是在 for 循环之后调用它吗? p.OrderBy(proj =&gt; proj.Created);
  • 午夜是一天中发生的第一件事,从 0 到 23:59 然后又回到零。如果当前是星期一的 23:30,则以 30 分钟时间表示,midnightTomorrow 是星期二的午夜。我叫它明天,因为今天是星期一,明天是星期二。如果它对您更有意义,您可以调用变量midnightTonight,但考虑一下,如果它是凌晨 1 点,“今晚午夜”可能合理地是一个小时前发生的午夜,因为您仍然处于“这个夜晚”(起源“今晚”一词)即当前的黑暗时期。可避免的歧义
【解决方案2】:

我认为你的部分问题是这个......

TimeSpan s = TimeSpan.FromHours(DateTime.Now.Hour);

这基本上是将当前时间向下四舍五入到最接近的小时。如果现在是晚上 11:30,那么...

// This is pseudocode
s = 23h
e = 24h
maxMin = e - s = 1h

因此,您允许randomGen.Next(maxMin) 生成最多整小时的分钟数,即使距离午夜不到一小时。要解决此问题,我认为您只需要获取 total time represented in hours...

TimeSpan s = TimeSpan.FromHours(DateTime.Now.TimeOfDay.TotalHours);

那你就...

// This is pseudocode
s = 23h30m
e = 24h
maxMin = e - s = 30m

因此,randomGen.Next(maxMin) 可能会导致最多,(略低于)30 分钟,将您带到午夜。

其他几点说明:

  • 我认为使用23.99 使得无法计算晚上11:59。
    TimeSpan s = TimeSpan.FromHours(DateTime.Now.TimeOfDay.TotalHours); //  23h30m
    TimeSpan e = TimeSpan.FromHours(23.99);                             // <24h
    //                 (e - s).TotalMinutes                             //    <30m
    int maxMin = (int)((e - s).TotalMinutes);                           //     29m
    int minutes = randomGen.Next(maxMin);                               //     28m (Max)
    TimeSpan t = start.Add(TimeSpan.FromMinutes(minutes));              //  23h58m
    
    e - s 距离午夜不到 30 分钟。 (int) 将其截断为 29 分钟。 Random.Next() 的参数是独占上限,因此传递29 意味着它可以返回的最大值仅为28
  • 这似乎可以简化SocialTimes 的操作,只需将其数据存储为TimeSpan 甚至DateTime,然后根据需要公开HourMinute 属性。
  • 请务必查看 List&lt;&gt; generic class,它早已取代了 ArrayList

【讨论】:

  • 谢谢培根。我更改了您建议的那行代码。说得通。现在我只需要等到一天结束才能尝试。
  • 好吧,没有什么能阻止您更改计算机上的时钟
  • Caius... 使用您的类将所有项目添加到列表后,如何对列表 p 进行排序?
猜你喜欢
  • 2013-02-05
  • 2017-06-25
  • 1970-01-01
  • 1970-01-01
  • 2013-06-20
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多