在我们的C#项目中,我们需要在没有时间的情况下表示日期.我知道DateTime的存在,但它也包含了一天中的时间.我想明确指出某些变量和方法参数是基于日期的.因此我不能使用该DateTime.Date属性
解决这个问题的标准方法是什么?当然,我不是第一个遇到这个?为什么DateC#中没有课?
有没有人有一个很好的实现使用结构和可能在DateTime上的一些扩展方法,并可能实现一些运算符,如==和<,>?
Mat*_*int 42
请允许我为此经典问题添加更新:
Jon Skeet的Noda Time库现在非常成熟,并且只有一个名为date的类型LocalDate.(在这种情况下,本地只对某人而言是本地的,不一定是运行代码的计算机的本地.)
名为date-only的类型Date是通过corefxlab项目向.NET Core添加的建议.您将在System.Time包中找到它,以及TimeOfDay类型和现有类型的几种扩展方法.
我已经研究过这个问题了,所以我也会分享几个这些类型必要性的原因:
仅日期和午夜日期值之间存在逻辑差异.
并非每个当地日都在每个时区都有午夜.示例:巴西的春季夏令时转换将时钟从11:59:59移动到01:00:00.
日期时间总是指一天中的特定时间,而仅日期可以指日期的开始,一天的结束或一天的整个范围.
如果未仔细观察时区,则将时间附加到日期可能会导致日期从一个环境传递到另一个环境时更改日期.这通常发生在JavaScript(其Date对象实际上是日期+时间)中,但在.NET中也很容易发生,或者在JavaScript和.NET之间传递数据时在序列化中发生.
DateTime使用XML或JSON(和其他)序列化将始终包括时间,即使它不重要.这非常令人困惑,特别是考虑到出生日期和周年纪念日等时间无关紧要的问题.
在架构上,它DateTime是一个DDD 值对象,但它在几个方面违反了单一责任原则:
它被设计为日期+时间类型,但通常仅用于日期(忽略时间)或仅用于时间(忽略日期).(TimeSpan也经常用于时间,但那是另一个话题.)
DateTimeKind附加到.Kind属性的值将单个类型拆分为三个类型.该Unspecified类型实际上是结构的原始意图,应该以这种方式使用.该Utc种与UTC专门对准值,Local那种对齐与环境的本地时区的价值.
有一个单独的标志的问题是,每次你消耗a DateTime,你应该检查.Kind以决定采取什么行为.框架方法都是这样做的,但其他人经常忘记.这确实是一个SRP违规,因为该类型现在有两个不同的原因需要改变(价值和种类).
这两个导致API编译的用法,但通常是荒谬的,或者由副作用引起奇怪的边缘情况.考虑:
// nonsensical, caused by mixing types
DateTime dt = DateTime.Today - TimeSpan.FromHours(3); // when on today??
// strange edge cases, caused by impact of Kind
var london = TimeZoneInfo.FindSystemTimeZoneById("GMT Standard Time");
var paris = TimeZoneInfo.FindSystemTimeZoneById("Romance Standard Time");
var dt = new DateTime(2016, 3, 27, 2, 0, 0); // unspecified kind
var delta = paris.GetUtcOffset(dt) - london.GetUtcOffset(dt); // side effect!
Console.WriteLine(delta.TotalHours); // 0, when should be 1 !!!
Run Code Online (Sandbox Code Playgroud)总之,虽然a DateTime 只能用于日期,但只有当每个使用它的地方都非常小心地忽略时间时才应该这样做,并且也非常小心不要尝试转换为UTC或其他时区.
Rob*_*ean 17
我怀疑没有专门的纯Date类,因为你已经有了DateTime它可以处理它.有Date会导致重复和混乱.
如果您想要标准方法,请查看DateTime.Date属性,该属性仅提供a的日期部分,DateTime时间值设置为午夜12:00:00(00:00:00).
MVC*_*CDS 11
我已经通过电子邮件发送了refsrcfeedback@microsoft.com,这就是他们的答案
马科斯,这不是一个问这样的问题的好地方.试试http://stackoverflow.com 简短的回答是你需要一个模型来表示一个时间点,而DateTime这样做,它是实践中最有用的场景.人类使用两个概念(日期和时间)来标记时间点的事实是任意的,对于分离是没有用的.
只有在有保证的地方才能脱离,不要仅仅为了盲目做事而做事.可以这样想:你有什么问题可以通过将DateTime分成日期和时间来解决?你现在没有什么问题?提示:如果您查看.NET框架中的DateTime用法:http://referencesource.microsoft.com/#mscorlib/system/datetime.cs#df6b1eba7461813b#references 您将看到大多数都是从方法返回的.如果我们没有像DateTime这样的单一概念,则必须使用out参数或Tuples来返回一对Date和Time.
HTH,Kirill Osenkov
在我的电子邮件中,我质疑是否是因为DateTime使用TimeZoneInfo来获取机器的时间 - 现在是正确的.所以我说这是因为它太耦合了,他们向我说话.
Cla*_*lay 10
当你需要一个简单的日期而不用担心时间部分,时区,本地和utc等时,我创建了一个简单的Date结构.
https://github.com/claycephus/csharp-date
System.DateOnly和System.TimeOnly types were recently added to .NET 6, and are available in the daily builds.
它们包含在 .NET 6 Preview 4 版本中。
看https://github.com/dotnet/runtime/issues/49036
它们位于 .NET 源代码中: