【问题标题】:Get the between time range from list of dates从日期列表中获取时间范围
【发布时间】:2017-04-08 07:28:47
【问题描述】:

我目前想从日期列表中获取日期范围(时间范围之间)。

例如:

现在是时候了

2017-04-08 18:00

我得到了这些从日期到日期:

public static string[] fromDates = new string[] { "2017-04-07 07:00", "2017-04-07 10:00", "2017-04-07 12:00", "2017-04-07 14:00", "2017-04-07 16:00" };
public static string[] toDates = new string[] { "2017-04-07 08:00", "2017-04-07 11:00", "2017-04-07 13:00", "2017-04-07 15:00", "2017-04-07 17:00" };

我正在使用此代码:

public static bool IsInRange(this DateTime dateToCheck, string[] startDates, string[] endDates, out string StartDate, out string EndDate)
    {
        DateTime startDate = new DateTime();
        DateTime endDate = new DateTime();

        bool isWithinRange = false;

        for (int i = 0; i < startDates.Length; i++)
        {
            startDate = Convert.ToDateTime(startDates[i]);

            isWithinRange = dateToCheck >= startDate;

            if (isWithinRange)
                break;
        }

        for (int y = 0; y < endDates.Length; y++)
        {
            endDate = Convert.ToDateTime(endDates[y]);

            isWithinRange = dateToCheck < endDate;

            if (isWithinRange)
                break;
        }

        StartDate = startDate;
        EndDate = endDate;

        return isWithinRange;
    }

我这样称呼它:

var isBetween = Convert.ToDateTime("2017-04-08 18:00").IsInRange(fromDates, toDates, out StartDate, out EndDate)

但我不能让它工作,IsInRange 方法中的StartDate 总是返回 true,它会从 fromDates 变量返回第一个索引,这是错误的。

我怎样才能让它像中间的时间?

我知道我可以这样做:

var isBetween = dateToCheck >= startDate && dateToCheck < endDate

但是只需要检查一个日期,如果和我的情况一样呢?

非常感谢您的回答。

谢谢

【问题讨论】:

    标签: c# asp.net


    【解决方案1】:

    我会首先将所有内容转换为更有用的对象模型:

    • 摆脱所有字符串(即在早期将字符串转换为更有用的东西)
    • 创建一个指示“日期/时间范围”的新类型,而不是两个集合。将错误的项目关联在一起有点让您受挫:开始值彼此不相关,它们与其对应的结束日期相关。

    如果您确实需要,您可以在方法中执行此操作,但最好为尽可能多的代码迁移到更丰富的对象模型。例如,假设您有:

    public sealed class DateTimeRange
    {
        public DateTime Start { get; }
        public DateTime End { get; }
    
        public DateTimeRange(DateTime start, DateTime end)
        {
            // TODO: Validate that start <= end
            Start = start;
            End = end;
        }
    
        public bool Contains(DateTime value) => Start <= value && value < End;
    }
    

    那么你的方法可以如下所示:

    public DateTimeRange FindRange(IEnumerable<DateTimeRange> ranges, DateTime value) =>
        ranges.FirstOrDefault(range => range.Contains(value));
    

    如果没有范围包含值,则返回null,否则确实包含值的第一个范围。

    (顺便说一句,我会在 Noda Time 中做所有这些,而不是作为更好的日期/时间 API,但我有偏见。)

    【讨论】:

    • 感谢您的建议@Jon Skeet,我想接受您的两个答案,但他们(stackoverflow)不允许我这样做:)。将尝试根据您的建议重新设计我的代码
    【解决方案2】:

    如果您想继续使用 yoir 设计,那么您应该简单地在一个循环中完成所有操作,而不是执行两次,因为您希望始终将第一个元素与第一个元素匹配,第二个与第二个元素匹配,等等。

    public static bool IsInRange(this DateTime dateToCheck, string[] startDates, string[] endDates, out DateTime StartDate, out DateTime EndDate)
        {
            if (startDates.Length != endDates.Length)
            {
                throw new ArgumentException("The arrays must have the same length");
            }
            StartDate = new DateTime();
            EndDate = new DateTime();
    
            for (int i = 0; i < startDates.Length; i++)
            {
                StartDate = Convert.ToDateTime(startDates[i]);
                EndDate = Convert.ToDateTime(endDates[i]);
    
                if (dateToCheck >= StartDate && dateToCheck <= EndDate)
                {
                    return true;
                }
            }
    
            return false;
        }
    

    但正如其他答案中已经说明的那样 - 你应该重新设计你的代码,因为它不是很容易维护和理解

    【讨论】:

    • 我正要发布这些确切的更改 :)
    • 感谢您的回答和建议@Pawel Gradecki,我想接受您的两个回答,但他们(stackoverflow)不允许我这样做:)。将尝试 Jon Skeet 的建议和你的重新设计我的代码。
    • 请注意,此时代码不会编译 - return 语句需要在循环之后。我建议你根本不需要isWithinRange - 你可以只返回true 而不是break 语句,如果你到达循环的末尾,则返回return false
    • @JonSkeet 是的,我在修复格式时搞砸了一些事情:/ 显然,循环后必须是 return 语句。我现在修复了代码。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-01-15
    • 1970-01-01
    • 2023-01-10
    • 2013-03-02
    • 1970-01-01
    • 2016-11-09
    相关资源
    最近更新 更多