四舍五入 .NET DateTime 毫秒,因此它可以适应 SQL Server 毫秒

Posted

技术标签:

【中文标题】四舍五入 .NET DateTime 毫秒,因此它可以适应 SQL Server 毫秒【英文标题】:Round .NET DateTime milliseconds, so it can fit SQL Server milliseconds 【发布时间】:2011-02-21 18:44:32 【问题描述】:

我想将日期时间值转换为我将从 SQL Server 2008 获得的值。

SQL Server 将毫秒截断为 3 位数,所以我已经截断了毫秒。但问题是你可以在这里看到:Milliseconds wrong when converting from XML to SQL Server datetime。 SQL Server 还有一个精度问题。

【问题讨论】:

【参考方案1】:

建议在 @RobSiklos 解决方案的基础上进行构建,因为以这种方式使用 SqlDateTime 会导致“日期”参数提供的时区信息丢失。通过添加对 DateTime.SpecifyKind 的调用,找到确保时区信息在转换点保持一致的最佳做法:

using System.Data.SqlTypes; // from System.Data.dll

public static DateTime RoundToSqlDateTime(DateTime date)

  return DateTime.SpecifyKind( new SqlDateTime(date).Value, date.Kind);

【讨论】:

点击链接了解更多关于SqlDateTime Struct的信息。【参考方案2】:

聚会有点晚了,但这里有一个解决方案,基于不同版本 SQL Server 的 datetime 数据类型的 SQL Server 文档:

SQL Server 2000 SQL Server 2005 SQL Server 2008

对于任何给定的日期/时间值,这应该为您提供与 SQL Server 完全相同的值:

public static class DateTimeExtensions

                                   //  milliseconds modulo 10:    0    1    2    3    4    5    6    7    8    9
    private static readonly int[]    OFFSET                  =   0 , -1 , +1 ,  0 , -1 , +2 , +1 ,  0 , -1 , +1  ;
    private static readonly DateTime SQL_SERVER_DATETIME_MIN = new DateTime( 1753 , 01 , 01 , 00 , 00 , 00 , 000 ) ;
    private static readonly DateTime SQL_SERVER_DATETIME_MAX = new DateTime( 9999 , 12 , 31 , 23 , 59 , 59 , 997 ) ;

    public static DateTime RoundToSqlServerDateTime( this DateTime value )
    
        DateTime dt           = new DateTime( value.Year , value.Month , value.Day , value.Hour , value.Minute , value.Second , value.Millisecond) ;
        int      milliseconds = value.Millisecond ;
        int      t            = milliseconds % 10 ;
        int      offset       = OFFSET[ t ] ;
        DateTime rounded      = dt.AddMilliseconds( offset ) ;

        if ( rounded < SQL_SERVER_DATETIME_MIN ) throw new ArgumentOutOfRangeException("value") ;
        if ( rounded > SQL_SERVER_DATETIME_MAX ) throw new ArgumentOutOfRangeException("value") ;

        return rounded ;
    

但是,对于 smalldatetime 或新的 datetime2 数据类型,它无法正常工作。

【讨论】:

这不是和'new SqlDateTime(myDateTime).Value'一样吗? @Simon,是的,看起来是一样的! :) +1 只是因为代码有助于与其他编程语言的互操作性。 ;)【参考方案3】:

这就是你想要的:

using System.Data.SqlTypes; // from System.Data.dll

public static DateTime RoundToSqlDateTime(DateTime date)

  return new SqlDateTime(date).Value;

【讨论】:

【参考方案4】:

这段代码应该可以工作:

        int ticksInMillisecond = 10000;
        DateTime t1 = DateTime.Now;
        DateTime t2 = new DateTime(t1.Ticks / ticksInMillisecond * ticksInMillisecond);

但考虑到 SQL Server 的精度问题,我宁愿在秒后将其截断为两位数:

        int precisionTicks = 100000;
        DateTime t1 = DateTime.Now;
        DateTime t2 = new DateTime(t1.Ticks / precisionTicks * precisionTicks);

【讨论】:

以上是关于四舍五入 .NET DateTime 毫秒,因此它可以适应 SQL Server 毫秒的主要内容,如果未能解决你的问题,请参考以下文章

将Rails DateTime四舍五入到最近的15分钟间隔

在net中怎么把datetime类型转换成毫秒数

.NET Compact Framework 上的 DateTime.Now 中的毫秒数始终为零?

测量代码执行时间

删除小时:秒:DateTime对象中的毫秒数

如何在 Flutter 中格式化 DateTime?删除 DateTime 中的毫秒数?