如何在.net中处理模糊的日期



我有一个系统,它从外部源获取信息,然后存储它以供以后显示。

其中一个数据项是日期。在源系统中,它们有一个模糊日期的概念,即不准确到特定的日子或有时也不准确到一个月。所以我得到的日期格式是:

dd/mm/yyyy
mm/yyyy
yyyy

我可以将这些解析为DateTime对象并使用这些对象,但在稍后呈现时,我需要能够确定日期的准确性,因为解析"2010"将导致日期为"01/01/2010"。我只想显示年份,所以需要知道它的原始精度。

我已经模拟了一个快速类来处理这个问题:

public class FuzzyDate
{
    public DateTime Date { get; set; }
    public DateType Type { get; set; }
}
public enum DateType
{
    DayMonthYear,
    MonthYear,
    Year
}

这将为我完成工作,我可以在解析上做一些事情来处理它,但我觉得这可能是一个相当常见的问题,可能有一个现有的更干净的解决方案。

有没有什么东西内置到。net来做这个?我看了一下文化方面的东西,但好像不太对。

回答你的问题:. net中没有任何内置的东西可以优雅地处理这个问题。

你的解决方案和我所见过的一样有效。您可能希望用ToString()方法的重写来修饰您的类,该方法将根据DateType适当地呈现日期。

下面是其他几个尝试解决这个问题的线程:

  • 不完整日期策略

  • 实现"部分日期"对象

祝你好运!

如果您的数据类型总是处理特定的时间段(即1972年是特定的时间段,但7月4日不是特定的),您可以将数据存储为开始时间和时间跨度。

  • 如果你的日期是"1972",那么开始日期就是19720101,时间跨度就是366天。
  • 如果您的日期为"07/1972",则开始日期为19720701,时间跨度为31天。
  • 如果你的日期是"04/07/1972",那么开始日期将是19720704,时间跨度将是1天。

这是一个可能的实现:

public struct VagueDate
{
    DateTime start, end;
    public DateTime Start { get { return start; } }
    public DateTime End { get { return end; } }
    public TimeSpan Span { get { return end - start; } }
    public VagueDate(string Date)
    {
        if (DateTime.TryParseExact(Date, "yyyy", null, 0, out start))
            end = start.AddYears(1);
        else if (DateTime.TryParseExact(Date, "MM/yyyy", null, 0, out start))
            end = start.AddMonths(1);
        else if (DateTime.TryParseExact(Date, "dd/MM/yyyy", null, 0, out start))
            end = start.AddDays(1);
        else
            throw new ArgumentException("Invalid format", "Date");
    }
    public override string ToString()
    {
        return Start.ToString("dd/MM/yyyy") + " plus " + Span.TotalDays + " days";
    }
}

当我开始阅读您的问题时,我很快得出结论,答案是实现您自己的FuzzyDate类。你瞧,这正是你所做的。

我可以想象您可能希望随着时间的推移添加功能(例如考虑到DateType的比较)。

我不相信在。net框架中有什么本质上能帮助你的,所以我认为你在做正确的事情。

我认为你走的路是对的。没有"模糊"日期或部分日期的概念,您需要建立自己的日期。

您可能需要更多的构造函数方法,例如

public FuzzyDate(int year)
{
   Date = new DateTime(year,1,1); // 1 Jan yy
   Type = DateType.Year;
}
public FuzzyDate(int year, int month)
{
   Date = new DateTime(year, month, 1); // 1 mm yy
   Type = DateType.MonthYear;
}
public FuzzyDate(int year, int month, int day)
{
   Date = new DateTime(year, month, day); // dd mm yy
   Type = DateType.DayMonthYear;
}

希望这有帮助,凯文

在我看来你的方法是对的。. net DateTime确实支持多种格式,但我想,鉴于所有这些格式都支持一个步骤(纳秒)的概念,那么将与特定的日期和时间相关。

我要做的一件事是使用可为空的值(或使用-1表示空语义)来表示月和日收集的数据。然后我将有一个工厂方法,它将接受一个DateType参数并返回一个DateTime。如果只有年份可用,并且客户端代码试图创建DateType.DayMonthYear,该方法将抛出一个异常。

public class FuzzyDate
{
    int _year;
    int? _month;
    int? _day;
    public DateTime Date { get; set; }
    public DateType Type { get; set; }
    public DateTime GetDateTime(DateType dateType) { // ...
}
public enum DateType
{
    DayMonthYear,
    MonthYear,
    Year
}

这可能看起来有点夸张,但是这种方法会显式地存储原始数据,并且只在请求时表示"伪造的"DateTime对象。如果要在内部持久化一个DateTime对象和一个DateType enum,就会失去一些分辨率。

据我所知,. net中没有为此内置任何内容,我的解决方案是基于可空值的解决方案,就像这样。

public class FuzzyDate
{
    private int Year;
    private int? Month;
    private int? Day;
    public FuzzyDate(int Year, int? Month, int? Day)
    {
        this.Year = Year;
        this.Month = Month;
        this.Day = Day;
    }
    public DateType DateType
    {
        get
        {
            if(Day.HasValue && Month.HasValue)
            {
                return DateType.DayMonthYear;
            }
            else if(Month.HasValue)
            {
                return DateType.MonthYear;
            }
            else
            {
                return DateType.Year;
            }
        }
    }
    public DateTime Date
    {
        get
        {
            return new DateTime(Year, Month.GetValueOrDefault(1), Day.GetValueOrDefault(1));
        }
    }
}
public enum DateType
{
    DayMonthYear,
    MonthYear,
    Year
}

您可以基于datetime创建自己的结构(用户定义的类型),允许00表示月,00表示日…然后还实现了icomparable,这样你就可以在上面做数学/比较了。

http://msdn.microsoft.com/en-us/library/k69kzbs1%28v=vs.71%29.aspx
http://msdn.microsoft.com/en-us/library/system.icomparable.aspx

相关内容

  • 没有找到相关文章

最新更新