为何100小时100分钟的TimeSpan会引发OleAut日期非法错误?
解决“Not a legal OleAut date”运行时错误(VB6遗留数据库对接场景)
这个问题我之前处理过类似的VB6遗留系统对接场景,根源是你没搞清楚OLE自动化日期(OADate)的范围限制和正确转换逻辑,咱们一步步拆解解决:
为什么会报错?
OADate有严格的范围限制:它只能表示1899年12月30日到9999年12月31日之间的日期/时间。你的代码里用DateTime.MinValue.AddTicks(timeSpan.Ticks),而DateTime.MinValue是0001年1月1日,这个日期远早于OADate的最小合法值,把它转成OADate自然会触发OverflowException。
而且你的转换逻辑绕了个没必要的弯:你想把TimeSpan转成OADate,但不需要绑定到DateTime.MinValue这个无效起点——VB6里的OADate本质是用小数表示时间相对于1899-12-30的天数:整数部分是日期偏移,小数部分是当天的时间比例(比如0.5就是中午12点)。
解决思路&修正代码
直接用TimeSpan.TotalDays获取时间跨度对应的总天数(这就是OADate需要的数值),不需要经过DateTime.MinValue:
using System; public class Program { public static void Main() { Console.WriteLine("Hello World"); TimeSpan timeSpan = TimeSpan.FromHours(100) + TimeSpan.FromMinutes(100); // 直接获取TimeSpan对应的总天数,这就是合法的OADate数值 double oaDateValue = timeSpan.TotalDays; // 如果需要转成DateTime(对接VB6数据库时,存的就是这个double值) DateTime resultDate = DateTime.FromOADate(oaDateValue); Console.WriteLine($"OADate数值:{oaDateValue}"); Console.WriteLine($"转换后的DateTime:{resultDate}"); } }
额外说明
- VB6里超过1天的时间跨度,会自动对应到1899年12月30日之后的日期(比如1.0就是1899-12-31 00:00:00,对应24小时),这完全匹配遗留数据库的存储逻辑
- 如果你的需求只是把时间跨度存成VB6兼容的OADate值,直接存储
oaDateValue这个double类型即可,不需要转成DateTime再转回去,更高效也避免了溢出风险
内容的提问来源于stack exchange,提问作者dale
相关产品推荐
相关产品推荐

