【问题标题】:C# Way to compare DateTime with maskC# 比较 DateTime 和掩码的方法
【发布时间】:2013-08-08 21:51:09
【问题描述】:

假设我们有一个DateTime,其中设置了一些字段,例如。只有MonthDay。这是一个面具。我们想通过这个掩码过滤 DateTimes 列表:

匹配 X,如果 X 具有月份和日期与掩码相同,以及其他字段中的任何其他值,如果掩码未设置它们(零)。

当然,我可以对每个可能的领域进行大量比较,但我相信 .NET 库。我正在寻找一种好方法,无论是否使用 LINQ。

这个的实际用法就像指定年份来查找今年的所有对应条目,或者指定月份和日期来查找这些月份和日期(任何年份和时间)的所有内容

编辑:我正在寻找一种本地方式来告诉代表“2010”和“2010/02/01”的日期存在某种关系(基本上,“2010”包括“2010/02/01”更多具体的)。我以前叫“2010”面具。

【问题讨论】:

  • 这些是否存储在某个集合中?大多数集合允许您实现IEqualityComparer<T>IComparer<T>,您可以为要检查的每个掩码提供一个实现并提供它。或者有一系列静态方法给 LINQ Where 调用。
  • @Adam Houldsworth:是的,我知道这些事情,我的问题是关于比较 DateTimes 的本地方式。我将包括这个问题。

标签: c# datetime filter compare mask


【解决方案1】:

首先,DateTime 不能很好地表示您的面具,因为它不能没有年份、月份或日期等。创建一个新类来表示具有 可为空值:

public class DateMask
{
    public int? Year { get; set; }
    public int? Day { get; set; }
    public int? Month { get; set; }
}

(您可以根据需要添加小时、秒、时区等属性。)

现在我们有了一个清楚地保存重要信息的掩码,编写查询相当简单:

public static IEnumerable<DateTime> FilterDates(IEnumerable<DateTime> dates, DateMask mask)
{
    var query = dates;
    if (mask.Year.HasValue)
        query = query.Where(date => date.Year == mask.Year);
    if (mask.Month.HasValue)
        query = query.Where(date => date.Month == mask.Month);
    if (mask.Day.HasValue)
        query = query.Where(date => date.Day == mask.Day);
    return query;
}

(您可以按照模式添加if/Where 以获取添加到掩码的其他属性。)

(您可能还想将该方法重构为DateMask 的实例方法。)

【讨论】:

  • 一个清晰的想法和干净的实现,谢谢!但这需要自定义类和比较。那么,没有本地方法来确定 DateTimes 的“部分相等”吗?
  • @Rast 不,没有,正如我在帖子开头所说的那样。 DateTime 必须代表一个特定的日期和时间,它的设计目的不是为了代表一些未知值的掩码。
【解决方案2】:

一个想法:

        List<DateTime> dt = new List<DateTime>();
        dt.Add(new DateTime(2010, 11, 11));
        dt.Add(new DateTime(2010, 7, 25));
        dt.Add(new DateTime(2011, 5, 11));
        dt.Add(new DateTime(2011, 11, 13));
        dt.Add(new DateTime(2013, 7, 13));
        dt.Add(new DateTime(2013, 1, 13));
        dt.Add(new DateTime(2012, 1, 11));

        string userInputMask = "201_-07-__";
        string mask = userInputMask.Replace("_",@"\d");
        var result = dt.Where(a => Regex.IsMatch(@String.Format("{0:yyyy-MM-dd}", a), @mask));

        result.ToList().ForEach(a=>Console.WriteLine(a));

结果:

2010-07-25 00:00:00

2013-07-13 00:00:00

\d 表示一个数字。为简单起见,用户输入屏蔽数字,例如下划线字符

【讨论】:

  • 疯狂与否,它可以工作:) 它基本上是 2 行代码,其余的只是上下文。虽然我不知道这是否正是你想要的。
  • 相当优雅且易于编码。不利的一面是,使用正则表达式意味着性能不佳
猜你喜欢
  • 1970-01-01
  • 2021-04-14
  • 2015-10-18
  • 1970-01-01
  • 2017-09-25
  • 2021-01-19
  • 1970-01-01
  • 2013-04-16
  • 1970-01-01
相关资源
最近更新 更多