DateTime 以毫秒为单位的表示?
Posted
技术标签:
【中文标题】DateTime 以毫秒为单位的表示?【英文标题】:DateTime's representation in milliseconds? 【发布时间】:2011-08-22 18:56:51 【问题描述】:我有一个 SQL 服务器时间戳,我需要将其转换为自 1970 年以来以毫秒为单位的时间表示形式。我可以用普通 SQL 做到这一点吗?如果没有,我已将其提取到 C# 中的 DateTime
变量中。是否有可能得到这个的毫秒表示?
谢谢, 泰迦。
【问题讨论】:
对于后一个问题:(now - Epoch).TotalMilliseconds
,其中now
和Epoch
是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 个滴答声,DateTime
和 TimeSpan
以比整毫秒更高的精度存储它们的值。 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 中。 根据MSDN,ToUnixTimeMilliseconds()
自.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);
希望对你有帮助
【讨论】:
以上是关于DateTime 以毫秒为单位的表示?的主要内容,如果未能解决你的问题,请参考以下文章
Realstudio (2011 4.2) 以毫秒为单位的日期
Freemarker 以毫秒为单位将时间戳转换为带有时区的日期