【问题标题】:Getting the first alarm time from set of alarms从一组警报中获取第一个警报时间
【发布时间】:2017-09-17 13:33:54
【问题描述】:

我目前正在开发一个带有多个(重复发生的)闹钟的闹钟。

我正在使用安装了 Microsoft IoT 和 UWP (C#) 的树莓派进行布局和底层算法。

我遇到的问题是检索下一个闹钟时间。

伪代码:

Select nextAlarm()
   For all alarms a
       if (((a.time >= now.time AND a.repeatDay == now.DayOfWeek) 
          OR a.repeatDay > now.DayOfWeek) AND a.dateTime < currentAlarm.dateTime)
              currentAlarm = a;

但是,每个闹钟都需要 O(n) 时间,并且函数 a.repeatDay > now.DayOfWeek 不是一个微不足道的函数(如果当天是星期三而下一个闹钟是星期一,则该函数不会' t 工作)。

我要问的是如何以上述函数工作的方式存储警报(并且最好比 O(n) 更快),或者如何存储所述问题已解决的重复天数。

目前使用 SQLite.net-pcl 包

Alarm 和 RepeatDay 类:

public class Alarm
{
    [PrimaryKey, AutoIncrement]
    public long Id { get; set; }

    [NotNull]
    public string Name { get; set; }

    [NotNull]
    public DateTime Time { get; set; }

    [NotNull]
    public int Repeat { get; set; }

    public Alarm(string name, DateTime time, RepeatWeek repeat)
    {
        this.Name = name;
        this.Time = time;
        this.Repeat = repeat;
    }

}

public class RepeatWeek
{
    int repeat = 0;
    public static implicit operator int(RepeatWeek w)
    {
        return w.repeat;
    }

    public void setDay(DayOfWeek w)
    {
        repeat |= 1 << (int)w;
    }

    public void removeDay(DayOfWeek w)
    {
        repeat &= ~(1 << (int)w);
    }

    public DayOfWeek getNext(DayOfWeek d, bool inclToday = false)
    {
        throw new NotImplementedException();
        return DayOfWeek.Monday; //Needs work
    }
}    

【问题讨论】:

  • 您只想要下一个预定的闹钟吗?
  • 是的,我目前被困在重复的日子里
  • 为什么不只检查报价并抓住价值最低的报价?
  • 我知道这种方法适用于单一发生的警报,但它如何处理重复警报
  • 如果您发布警报类/对象的外观。我可以给你更多的建议。

标签: c# datetime time uwp data-management


【解决方案1】:

我已经尝试过实现 GetNextDay。然后,实现 Alarm.GetNext 就变得很简单,一个更简单的 LINQ 查询可以满足您的要求。我留了一些给你实现,所以你可以说你做到了。

public class Alarm
{
    public long Id { get; set; }

    public string Name { get; set; }

    public DateTime Time { get; set; }

    public int Repeat { get; set; }

    public Alarm(string name, DateTime time, RepeatWeek repeat)
    {
        this.Name = name;
        this.Time = time;
        this.Repeat = repeat;
    }

    public DateTime GetNext()
    {
        var includeToday = true;
        if (DateTime.Now.TimeOfDay > Time.TimeOfDay)
        {
            includeToday = false;
        }

        var repeat = new RepeatWeek(Repeat);
        var nextDayOfWeek = repeat.GetNextDay(includeToday);
        return MergeDayOfWeekAndTime(nextDayOfWeek, Time);
    }

    private DateTime MergeDayOfWeekAndTime(DayOfWeek? nextDayOfWeek, DateTime Time)
    {
        //Left as exercise to the reader.
        throw new NotImplementedException();
    }
}

public class RepeatWeek
{
    int Repeat;

    public RepeatWeek(int repeat = 0)
    {
        Repeat = repeat;
    }

    public static implicit operator int(RepeatWeek w)
    {
        return w.Repeat;
    }

    public void setDay(DayOfWeek w)
    {
        Repeat |= 1 << (int)w;
    }

    public void removeDay(DayOfWeek w)
    {
        Repeat &= ~(1 << (int)w);
    }

    public static DayOfWeek FollowingDayOfWeek(DayOfWeek day)
    {
        if (day == DayOfWeek.Saturday)
        {
            return DayOfWeek.Sunday;
        }
        else
        {
            return day + 1;
        }
    }

    public DayOfWeek? GetNextDay(bool inclToday = false)
    {
        var inspect = DateTime.Now.DayOfWeek;
        if (!inclToday)
        {
            inspect = FollowingDayOfWeek(inspect);
        }

        for (int i = 0; i < 7; i++)
        {
            if ((Repeat & (1 << (int)inspect)) > 0) return inspect;
            inspect = FollowingDayOfWeek(inspect);
        }
        return null;
    }
}

[TestClass]
public class MyTestClass
{
    [TestMethod]
    public void GetNextDayOfWeek()
    {
        var repeat = new RepeatWeek();
        repeat.setDay(DayOfWeek.Monday);
        repeat.setDay(DayOfWeek.Tuesday);
        var expected = DayOfWeek.Monday;
        if (DateTime.Now.DayOfWeek == DayOfWeek.Monday)
        {
            expected = DayOfWeek.Tuesday;
        }

        var actual = repeat.GetNextDay();
        Assert.AreEqual(expected, actual);
    }

    [TestMethod]
    public void GetNextAlarm()
    {
        //Populate this yourself.
        var alarms = new List<Alarm>();
        var nextAlarm = alarms.Select(a => a.GetNext()).OrderBy(a => a.Ticks).FirstOrDefault();
    }
}

【讨论】:

  • 接受,它显示了一周中的几天的迭代。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-11-22
  • 1970-01-01
相关资源
最近更新 更多