温馨提示:本文翻译自stackoverflow.com,查看原文请点击:其他 - C#/EF Core: Working with (historical) dates/periods
c# entity-framework-core asp.net-core-mvc database-schema

其他 - C#/ EF Core:处理(历史)日期/期间

发布于 2020-03-27 11:17:43

给定一个使用ASP.NET Core Mvc和SQL Server和EF Core的C#网站。

对于一个爱好项目,我正在寻找旧报纸,文件并寻找特定的建筑物。每次我找到此类建筑物的信息时,我都会尝试写下日期信息。这样我就可以跟踪这座建筑物在哪个时期。

假设我碰到Build X并看到了日期1880。我写下了date 1880几周后,我再次遇到了X楼,看到日期:16/03/1877。我现在知道建筑物可以肯定地从16/03/1877到1880。

期间:16/03/1877-1880

  • Now some buildings don't have any date info.
  • Some buildings have only a single date (maybe with extra research another one could be found)
  • Some buildings might have information that it existed in the 17th century (without a specific year or date).
  • dates can contains year, year+month or year+month+day

Now what would be the best to store this in the database and represent this in a model.

Would 2 properties on a model be sufficient?

public class Building {
[DataType(DataType.Date)]
        [DisplayFormat(DataFormatString = "{0:yyyy-MM-dd}", ApplyFormatInEditMode = true)]
  public DateTime? Date1 { get; set; }
[DataType(DataType.Date)]
        [DisplayFormat(DataFormatString = "{0:yyyy-MM-dd}", ApplyFormatInEditMode = true)]
public DateTime? Date2 { get; set; }
}

Would it be suitable for search filters on the website. E.g. searching everything between 1830 - 1930 or everything from 17th century.

With the last question, I mean, how would you write a linq query if there is only one date given for a building (e.g. 1835). Would each query contain an extra check for the nullable date in case there is only a single date given? or are there better scenarios?

.Where(x => x.Date1 != null && x.Date1 >= 1830 && (x.Date2 == null || x.Date2 <= 1930))

Or is saving a DateTime? object not a good idea and better to store a short or integer and only keep track of the year component (if any)?

查看更多

查看更多

提问者
juFo
被浏览
169
Chris Pratt 2019-07-03 23:22

Really, your problem boils down to showing exact vs "fuzzy" dates. There's no one single strategy, but I've had a somewhat similar requirement before and handled it by having a start date, a fuzzy start, an end date, and a fuzzy end, all nullable.

如果您完全知道日期的确切部分,请使用实际的datetime字段。例如,如果您只知道1880,则将其存储为1880-01-01如果您知道年和月,则只需输入天01,当然,如果您知道完整的日期,则可以存储该日期。现在,理所当然,这可能会带来问题。您怎么知道它不是从1880年1月1日开始建造的,而是从一般意义上来说是1880年建造的?好吧,这取决于您决定如何处理这些情况。您可以假定任何01与该日期部分的空值相同。无论出于何种原因,建筑物都不会在1月1日或实际上在每个月的1号开放,但是那里总是有例外。

如果确实需要更高的精度,则可能需要分开日期并将其逐字存储为年,月和日-所有可为int的int列。然后,您可以简单地将其拼凑在一起,但是可以随时进行显示。

“模糊的”日期列将是字符串,并且您将在其中存储更多的星云“日期”,例如“维多利亚时代”,即您可能没有真实的日期甚至年份,但您知道它是在一段时间内。您可以对“ 19世纪”之类的东西进行同样的操作,但是我个人更喜欢将其存储为1800-01-01,然后暗示应该在有该日期的日期将其显示为“ 19世纪”。

另一种选择是同时使用日期和模糊文本。例如,您可以将其存储为1800-01-01 “ 19世纪”,然后基于模糊文本的存在不为空,来确定它实际上不是1800年1月1日。这可以帮助解决前面描述的歧义问题,因为您可以在所有此类情况下都这样做。例如,如果您只知道“ 1880年7月”,则可以将其存储在模糊文本中,并将日期设置为1880-07-01然后,基于模糊文本的存在,您可以选择将01部分解密为基本上为零,而不是按月实际值。如果没有设置模糊文本,则假定它是确切的日期。

至于在模型上表示,我不会使用实际DateTime属性或DisplayFormat拥有可以处理逻辑并返回预格式化的“日期”的实用程序方法会更好地为您服务。然后,您只需做类似的操作@building.GetBuiltDisplay(),并返回所有已经格式化的信息(包括开始和结束,如果有的话)。