DateTime.MaxValue.Ticks changes when passed to constructor
我试图将
1 2 3 4 5 6 7 | DateTime dt = DateTime.MaxValue; //here it is 315537897599999999 OfferSetting setting = new OfferSetting(settingCode , (Equals(row["AccountId"],"")) ? null : row["AccountId"].ToString() , (Equals(row["Arguments"],"")) ? null : row["Arguments"].ToString() , (Equals(row["StartDate"],"") || Equals(row["StartDate"], DBNull.Value)) ? DateTime.MinValue : Convert.ToDateTime(row["StartDate"]) , (Equals(row["EndDate"],"") || Equals(row["StartDate"], DBNull.Value)) ? dt : Convert.ToDateTime(row["EndDate"])); |
进入
1 2 3 4 5 6 7 8 9 10 11 | public OfferSetting(SettingCode settingCode, string accountId, string arguments, DateTime startDate, DateTime endDate) : base(MoeState.New) { this.Id ="-1"; this.OfferSettingId ="-1"; this.SettingCode = settingCode; this.AccountId = accountId; this.Arguments = arguments; this.StartDate = startDate; this.EndDate = endDate; //here it is 3155378975990000000 } |
有什么想法吗?
我没有责备-我只是试了试,但不能让它责备。您将需要进行调试,如果这样做很容易,请重写代码以将行["enddate"]分配给变量(即使是临时的),这样您至少可以看到该变量中的内容。
仅供参考,在您的第二种情况下,您似乎正在测试第["enddate"]行和第["startdate"]行,这可能是导致问题的原因。
(Equals(row["EndDate"],"") || Equals(row["StartDate"], DBNull.Value)) ? dt : Convert.ToDateTime(row["EndDate"]));
正如其他人所建议的:
- 尝试使用可为空而不是MaxValue。您可能会遇到不同时区和地区的问题,甚至没有意识到(特别是当您的代码在不同的机器上运行时)。
- 考虑使用datetimeoffset而不是datetime,因为它表示"即时时间"而不是"日历时间"。更多讨论请参见此处。(您最好还是使用nullable。)
简单地通过一个构造函数参数传递一个值绝对不能改变这个值,所以您可以消除它的那部分。
更可能的是,存在精度损失问题。这可能发生在将值存储到数据库中或检索该值时。
在存储方面,如果您确实需要存储
在检索方面,您的一些代码似乎遭受了一种常见的反模式。
不要这样做:
1DateTime dt = Convert.ToDateTime(row["yourfield"].ToString());相反,请执行以下操作:
1DateTime dt = (DateTime) row["yourfield"];
当您转换为字符串,然后解析该字符串时,可能会丢失精度。此外,在某些情况下,特定于文化的格式或非公历日历可能会受到影响。只需拆开它,就可以保持原来的类型。不需要字符串。
其他类型也一样,包括整数、布尔值和字符串。基础数据库客户端已经进行了从本机数据库类型到适当的.NET类型的最佳转换。不需要再做那个工作了。
我明白了,我只是个白痴,它把错误的值传递给构造函数。
可以为空的datetime结构将命名为datetime?例如
1 | DateTime? ndt=null; |
在拨动实际值字段之前,还需要检查(hasValue())。
1 | if(ndt.HasValue()){/*do what you meant to */} |