是否有一种在C#中表示不确定日期的标准方法?

我正在玩一些历史数据,其中我知道一些日期准确(即dd / mm / yyyy),而其他日期只是yyyy而其他日期是yyyy? (即年份不确定)。 我甚至遇到了fl,这显然意味着“蓬勃发展”。

目前我正在使用DateTime类,它似乎不支持这种不确定性的标记/表示。 有没有解决这个问题的标准方法?

有关于表示大致时间的方法的各种学术论文,例如http://www.musiccog.ohio-state.edu/Humdrum/representations/date.rep.html

如果您想要处理历史文档的全部范围以及您对其中任何一个的大致知识,那么使用DateTime值并不是简单的bool / nullable操作。

我还没有看到一个C#库来处理这个问题。 我自己的C#自然语言引擎可以理解各种日期时间短语,但是针对不同的问题而设计 – 它可以接受一个不精确的问题并查询具有精确值的数据库。

它具有特定日期,日期范围,已知年份(但没有月/日),已知年份+月份(但没有日期),半无限范围(例如在给定日期之前或之后)的类别, …并且使用它们可以构建针对数据库的查询,或者可以枚举可能意味着的所有可能的日期范围。 例如,你可以问它“去年下午4点以后打电话的人”,它可以生成适当的SQL查询。

如果你想做到这一点,那就不容易了! 如果我是你,我将捕获一个字符串值,其中包含原始文本,以及您选择用于DateTime值的任何表示。 通过这种方式,您可以使表示更加智能,以涵盖更多案例,最终能够处理“1940年至1945年9月16日之间的某些事情”。

最初,您可能只想存储字符串表示和两个DateTime值 – 尽可能早和最晚可能的日期。 这涵盖了您将看到的大多数情况,并且很容易查询。 您可以将Datetime值保留为null,也可以将其设置为最大值或最小值,以表示半无限范围,例如“1900之后”。

我会考虑创建一个包装DateTime(或DateTimeOffset)的类,并有其他字段来表示日期的哪些部分是确定的,哪些部分不是。

然后,您可以将月,日和年字段显示为可空值,以反映日期的哪些部分已知。

如果不确定性是二元的(即,日期是已知的或未知的),那么我将使用可以为空的DateTime类型。 否则,我会考虑使用额外的枚举属性创建一个包装器结构:

public enum DateConfidence { Certain, Unknown, YearOnly, ApproximateYearOnly } 

DateTime? 是可以为空的。 这可能是你最好的选择。 另一种选择是DateTime.MinValue (或MaxValue )。

[编辑]实际上,重读你的问题,我认为你最好的办法是设计一个符合你确切目的的自定义类。

无线电碳测年将是一个典型的例子。 你需要一个有两个成员的class级。 猜测的日期和误差估计。 后者通常以年份表示,但您可以自由选择任何单位。 请注意,DateTime无法在0 BCE之前表示日期,因此请将其作为年份的简单int。 避免让它变得更加花哨,猜测正确的月份对于1000年之前的任何日期都没有意义。

.Net中没有这样的类,所以最好是创建自己的类,其中可空属性表示所有必需的日期字段。

这将为您提供最大的灵活性,并允许处理您可能拥有的任何场景(如果不是 – 您只需重构您的类,编译器将帮助您找到需要完成修复的位置)。

我对这种情况的偏好是创建具有一定确定性属性的日期范围对象。

像这样的东西:

 public struct HistorialDateRange { public DateTime StartDate { get; } public DateTime EndDate { get; } public double Confidence { get; } /* range [0.0, 1.0] */ } 

然后我会有一系列构造函数,让我设置年,月范围或单个日期,每个都有一个置信度值。 信心给了我一个模糊比较的“橡皮”数字。

如果我设置一天, StartDateEndDate应该包含该日期。

然后,您可以根据需要确定HistorialDateRange对象之间的比较。 我希望方法可以让我问他们是否截然不同,重叠等等。

希望有所帮助。

稍微偏出框就可以回答您的问题。

如果您正在处理您描述的非结构化历史数据,我实际上会将它们捕获为字符串 – 就像它一样。 数据的实际含义来自其使用位置的上下文。 您可能会争辩说我们正在失去意义,但实际上强制使用具有大量可空/任意值的数据到DateTime对象也是无意义的。 以此为例:

  • 1910年至1929年
  • <1960年或1960年之前
  • 1950年7月或1950年7月以后

  • 1950年 – 现在或1950年 – 现在

除非您能够满足各种可能性,否则将期间文本早期映射到DateTime等结构对象可能会丢失数据。 以“现在/现在”为例,它是一个相对值,只有在使用它时才能替换它,而不是在解析或转换值时。 在特定日期之前和之后你会如何储存? 当然,通过大量的建模工作,您可以以结构化的方式捕获所有这些信息,以实现所有可能性。

句点文本应该在何时以及如何使用的上下文中进行解释,如果适合您,您可以使用任何解析方法或自然语言解析。 如果解析失败,您可以随时改进它,但在读取或迁移数据时,您不应该在一开始就丢失数据的语义。