【问题标题】:DateTime's representation in milliseconds?DateTime 以毫秒为单位的表示?
【发布时间】:2011-08-22 18:56:51
【问题描述】:

我有一个 SQL 服务器时间戳,我需要将其转换为自 1970 年以来以毫秒为单位的时间表示形式。我可以用普通 SQL 做到这一点吗?如果没有,我已将其提取到 C# 中的 DateTime 变量中。是否有可能得到这个的毫秒表示?

谢谢,
泰迦。

【问题讨论】:

  • 对于后一个问题:(now - Epoch).TotalMilliseconds,其中nowEpoch 是DateTime 对象。

标签: c# sql-server datetime


【解决方案1】:

您可能正在尝试转换为类似 UNIX 的时间戳,采用 UTC:

yourDateTime.ToUniversalTime().Subtract(
    new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc)
    ).TotalMilliseconds

这也避免了夏季问题,因为 UTC 没有这些问题。

【讨论】:

  • 这给出一个分数作为输出,例如:“1552678714362.79”“.79”来自哪里?
  • @SharifYazdian 这正是您所期望的,它是 0.79 毫秒。系统时间以滴答声为单位。鉴于 1 毫秒有 10000 个滴答声,DateTimeTimeSpan 以比整毫秒更高的精度存储它们的值。 0.79 毫秒 = 7900 滴答声。如果需要整数,可以使用long ms = myTimeSpan.TotalTicks / 10000;
  • 在 .NET Core (>2.1) 中,您可以使用 DateTime.UnixEpoch 而不是声明日期。
  • 这段代码有一个问题:它假设DateTime(查看ToUniversalTime合同中的注释)是当地时间,但它可能不是。例如,使用DateTime.UtcNow 采样时间很常见,或者它可能位于另一个时区。
  • @ceztko 对于DateTime.UtcNow,这不是问题,因为 UtcNow DateTime 的 Kind 属性设置为 Utc,ToUniversalTime 方法不会转换任何内容。如果您的 DateTime 代表的时区不是本地或 UTC,则可能存在问题(但在这种情况下,您最好使用 DateTimeOffset 而不是 DateTime)
【解决方案2】:

在 C# 中,您可以编写

(long)(date - new DateTime(1970, 1, 1)).TotalMilliseconds

【讨论】:

  • 我建议投给long 而不是int :)
  • new DateTime(1970, 1, 1).AddMilliseconds(myDateAsALong); 如果你想走另一条路。
  • @JackMorrissey: AddMilliseconds() 需要 double 类型的参数。隐式转换可以解决这个问题,但可能值得注意。
  • @JonSkeet 为什么建议转换为 long 而不是 int? :)
  • @Roxy'Pro: int.MaxValue 以毫秒为单位大约是 25 天。这不太可能有用。
【解决方案3】:

从 .NET 4.6 开始,您可以使用 DateTimeOffset 对象来获取 unix 毫秒数。它有一个构造函数,它接受一个DateTime 对象,所以你可以直接传入你的对象,如下所示。

DateTime yourDateTime;
long yourDateTimeMilliseconds = new DateTimeOffset(yourDateTime).ToUnixTimeMilliseconds();

如其他答案中所述,请确保 yourDateTime 指定了正确的 Kind,或先使用 .ToUniversalTime() 将其转换为 UTC 时间。

Here您可以了解更多关于DateTimeOffset的信息。

【讨论】:

  • ToUnixTimeMilliseconds() 实际上并不存在于 .Net 3.5 中。
  • 根据MSDNToUnixTimeMilliseconds()自.NET 4.6起可用
  • @kayleeFrye_onDeck OP 询问从数据库中提取的时间戳,因此您对 .Now 的评论并不直接适用于这个问题。
【解决方案4】:
SELECT CAST(DATEDIFF(S, '1970-01-01', SYSDATETIME()) AS BIGINT) * 1000

这不会为您提供完整的精度,但DATEDIFF(MS... 会导致溢出。如果秒数足够好,应该这样做。

【讨论】:

    【解决方案5】:

    这是将日期时间转换为 unixtimestampmillis C# 的另一种解决方案。

    private static readonly DateTime UnixEpoch = new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc);
    
    public static long GetCurrentUnixTimestampMillis()
    {
        DateTime localDateTime, univDateTime;
        localDateTime = DateTime.Now;          
        univDateTime = localDateTime.ToUniversalTime();
        return (long)(univDateTime - UnixEpoch).TotalMilliseconds;
    } 
    

    【讨论】:

      【解决方案6】:

      DateTimeExtensions 类中有ToUnixTime()ToUnixTimeMs() 方法

      DateTime.UtcNow.ToUnixTimeMs()

      【讨论】:

        【解决方案7】:

        使用安多玛的答案,这就是我正在做的事情

        你可以创建一个这样的结构或类

        struct Date
            {
                public static double GetTime(DateTime dateTime)
                {
                    return dateTime.ToUniversalTime().Subtract(new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc)).TotalMilliseconds;
                }
        
                public static DateTime DateTimeParse(double milliseconds)
                {
                    return new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc).AddMilliseconds(milliseconds).ToLocalTime();
                }
        
            }
        

        您可以在代码中使用它,如下所示

        DateTime dateTime = DateTime.Now;
        
        double total = Date.GetTime(dateTime);
        
        dateTime = Date.DateTimeParse(total);
        

        希望对你有帮助

        【讨论】:

          猜你喜欢
          • 2019-08-08
          • 1970-01-01
          • 1970-01-01
          • 2019-02-24
          • 2015-09-16
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2012-03-26
          相关资源
          最近更新 更多