You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何避免DateTime.Now赋值多变量时的Ticks差异问题

解决DateTime Ticks差异导致的校验不通过问题

看起来你遇到的核心问题是DateTime的高精度Ticks在对比时引发误判——虽然日期、时、分、秒都完全匹配,但因为原始DateTime.Now包含毫秒甚至更细的精度,而后续表单生成的_eventItem.StartDateTime可能丢失了这部分精度,导致直接对象对比时判定为不相等。

先澄清一个关键细节:C#里的DateTime是值类型,直接赋值(比如_uneditedEvent.StartDateTime = _eventStartDate)就会完整复制所有属性(包括Ticks),所以你初始化时的_uneditedEvent和_eventStartDate的Ticks肯定是完全一致的,问题不在复制环节,而是出在后续_eventItem的日期时间生成逻辑上。

下面给你几个可行的解决方案:

方案1:统一日期时间精度,截断到秒(或你需要的粒度)

从源头统一日期时间的精度,去掉毫秒及以下的部分,这样对比时就不会因为微小的Ticks差异导致误判。

修改初始化代码:

var startDate = DateTime.Now;
// 截断到秒,去除毫秒及更细的精度
var truncatedStartDate = startDate.AddTicks(-(startDate.Ticks % TimeSpan.TicksPerSecond));
var endDate = truncatedStartDate.AddHours(1);
var truncatedEndDate = endDate.AddTicks(-(endDate.Ticks % TimeSpan.TicksPerSecond));

_eventStartDate = truncatedStartDate;
_eventEndDate = truncatedEndDate;
_uneditedEvent = new EventItem() {
    StartDateTime = _eventStartDate,
    EndDateTime = _eventEndDate,
};

同时,当用户在表单中选择日期时间后,生成_eventItem.StartDateTime和_eventItem.EndDateTime时,也要做同样的截断处理,确保两边的精度完全一致。

方案2:对比时忽略高精度差异,只校验到关心的级别

如果不想修改日期时间的生成逻辑,可以在对比时跳过Ticks的高精度部分,只校验你真正关心的年、月、日、时、分、秒。

可以封装一个辅助方法:

bool AreDateTimeEqual(DateTime dt1, DateTime dt2)
{
    return dt1.Year == dt2.Year &&
           dt1.Month == dt2.Month &&
           dt1.Day == dt2.Day &&
           dt1.Hour == dt2.Hour &&
           dt1.Minute == dt2.Minute &&
           dt1.Second == dt2.Second;
}

然后修改你的校验条件:

if (_uneditedEvent.Type != _eventItem.Type || 
    _uneditedEvent.CustomerCode != _eventItem.CustomerCode || 
    _uneditedEvent.ProjectCode != _eventItem.ProjectCode || 
    !AreDateTimeEqual(_uneditedEvent.StartDateTime, _eventItem.StartDateTime) || 
    !AreDateTimeEqual(_uneditedEvent.EndDateTime, _eventItem.EndDateTime) || 
    _uneditedEvent.Notes != _eventItem.Notes)
{
    var action = await _pageDialogue.DisplayAlertAsync("Unsaved Changes", "Do you want to abandon this event?", "Yes", "No");
    switch (action)
    {
        case false: return;
    }
}

或者用更简洁的方式,通过时间差判断:

Math.Abs((_uneditedEvent.StartDateTime - _eventItem.StartDateTime).TotalSeconds) < 1

方案3:使用DateTimeOffset替代DateTime(可选)

如果你的场景涉及时区,DateTimeOffset比DateTime更可靠,对比逻辑也更清晰,同样可以用上面的精度截断或差异判断方式处理。

总结一下,你的问题本质不是复制DateTime的问题(C#值类型赋值已经是完整复制),而是高精度Ticks在表单交互后丢失导致的对比不匹配,上面的方案都能解决问题,推荐方案1,从源头统一精度,彻底避免后续的对比隐患。

内容的提问来源于stack exchange,提问作者Bodungus

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.28 04:21:40