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

WinCC Ticks与C# DateTime双向转换的精度问题排查

解决WinCC Flexible Ticks与C# DateTime双向转换的精度问题

问题根源

你的转换逻辑中,DateTimeToSiemensTime方法的计算公式错误,这是导致双向转换出现误差的核心原因:

  • WinCC的Time_ms(Ticks)单位是1e-6天(即1个Tick等于百万分之一天)
  • C# TimeSpan.Ticks的单位是100纳秒,1天 = 86400秒 = 8.64×10¹¹个C# Tick
  • 正确转换公式应为:WinCC Tick = (C# TimeSpan Ticks) / 864000.0,而非原代码中的除以1e6

此外,大数值用double运算会存在微小精度损耗,但只要公式正确,误差会缩小到可忽略的级别。

修正后的代码

1. WinCC Ticks转C# DateTime

保留原有逻辑,补充时间一致性处理避免时区问题:

DateTime SiemensTimeToDateTime(double siemensTime)
{
    // WinCC固定起始时间:1899-12-30 00:00:00
    var startDateTime = new DateTime(1899, 12, 30, 0, 0, 0, DateTimeKind.Utc);
    // 1个WinCC Tick对应1e-6天,直接转换为时间跨度
    var timeSpan = TimeSpan.FromDays(siemensTime / 1_000_000d);
    return startDateTime.Add(timeSpan);
}

2. C# DateTime转WinCC Ticks

修正核心计算公式,同时统一时区避免偏差:

double DateTimeToSiemensTime(DateTime dateTime)
{
    var startDateTime = new DateTime(1899, 12, 30, 0, 0, 0, DateTimeKind.Utc);
    // 统一转换为UTC时间,避免本地时区差异影响计算
    if (dateTime.Kind != DateTimeKind.Utc)
        dateTime = dateTime.ToUniversalTime();
    
    var timeSpan = dateTime.Subtract(startDateTime);
    // 正确转换:1天=8.64e11 C# Tick,1 WinCC Tick=1e-6天 → 8.64e11 / 1e6 = 864000
    return timeSpan.Ticks / 864000.0;
}

验证测试

用你的测试值验证:

double mainTick = 45590722754.8727; // 对应日志中的"2024-10-25 17:20:46"
DateTime dt = SiemensTimeToDateTime(mainTick);
double calcTick = DateTimeToSiemensTime(dt);
double diff = calcTick - mainTick; 
// 此时diff会趋近于0,误差在double精度范围内(约1e-12级别,完全可忽略)

额外优化建议

如果需要彻底消除浮点精度损耗,可以将WinCC Tick转换为整数微秒处理:

  • 1 WinCC Tick = 86.4微秒(1e-6天 = 0.0864秒 = 86.4微秒)
  • 用64位整数存储微秒数进行双向转换,完全规避浮点运算的精度问题。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.16 11:11:16