#1 楼
我假设您的意思是Unix时间,它定义为自1970年1月1日午夜(UTC)以来的秒数。 private static readonly DateTime epoch = new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc);
public static DateTime FromUnixTime(long unixTime)
{
return epoch.AddSeconds(unixTime);
}
UPDATE 2020
您可以使用DateTimeOffset
DateTimeOffset dateTimeOffset = DateTimeOffset.FromUnixTimeSeconds(epochSeconds);
DateTimeOffset dateTimeOffset2 = DateTimeOffset.FromUnixTimeMilliseconds(epochMilliseconds);
完成此操作,如果需要
DateTime
对象而不是DateTimeOffset
,则可以调用DateTime
属性 DateTime dateTime = dateTimeOffset .DateTime;
评论
为了使其正常工作,我必须将.AddSeconds更改为.AddMilliseconds。您将需要知道您的数字是秒还是毫秒,以便获得正确的结果。因此,例如以下日期:1406310305188(2014年7月25日)。 epochconverter.com还将让您检查转换结果。
– jrandomuser
2014年7月30日在16:58
您应该将参数类型更改为double(因为AddSeconds接受double,因此将向下转换为double),或者在方法描述中添加免责声明,即在参数的64位精度中仅保留53。
– tomosius
16年5月3日在17:04
@jrandomuser:Unix纪元时间通常表示为自纪元以来的秒数。自从大纪元以来(例如JavaScript),使用毫秒已经很普遍了,但是经典的定义是秒。底线是,只要知道您的输入值是什么(秒,毫秒,刻度线等),然后使用正确的AddXYZ方法即可。
– T.J.拥挤者
17年7月16日在8:11
首先尝试使用AddMilliseconds,如果年份仍为1970,则执行AddSeconds。这样,它将一直工作,而不必担心毫秒或秒。另外,您可以防止溢出异常。大量传递给AddSeconds将使代码崩溃
– Tono Nam
19-10-16在18:52
#2 楼
.Net(v4.6)的最新版本刚刚添加了对Unix时间转换的内置支持。这包括以秒或毫秒表示的往返Unix时间。以秒为单位的Unix时间到
DateTimeOffset
:DateTimeOffset dateTimeOffset = DateTimeOffset.FromUnixTimeSeconds(1000);
DateTimeOffset
到Unix的时间,以秒为单位:long unixTimeStampInSeconds = dateTimeOffset.ToUnixTimeSeconds();
< br Unix时间以毫秒为单位:
DateTimeOffset
:DateTimeOffset dateTimeOffset = DateTimeOffset.FromUnixTimeMilliseconds(1000000);
DateTimeOffset
以毫秒为单位的Unix时间: long unixTimeStampInMilliseconds= dateTimeOffset.ToUnixTimeMilliseconds();
注意:这些方法与
DateTimeOffset
之间相互转换。要获得DateTime
表示形式,只需使用DateTimeOffset.DateTime
属性:DateTime dateTime = dateTimeOffset.UtcDateTime;
评论
我得到的“ DateTimeOffset”不包含“ FromUnixTimeSeconds”的定义,我该如何解决呢?
–快乐鸟
17年7月24日在14:44
@HappyBird您是否在.NET 4.6或更高版本上?
– i3arnon
17年7月24日在15:31
一样-4.7.2且DateTimeOffset没有FromUnixTimeMilliseconds方法...
– Mikhail_Sam
18-10-9在8:51
我知道了。我不需要创建新对象。这是一种静态方法。
– Mikhail_Sam
18-10-9在9:23
乍一看,我发现默认值有点令人困惑。公元前1000是从毫秒转换为秒的因子。
–蓝光
6月9日在1:41
#3 楼
归功于LukeH,我整理了一些易于使用的扩展方法:public static DateTime FromUnixTime(this long unixTime)
{
var epoch = new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc);
return epoch.AddSeconds(unixTime);
}
public static long ToUnixTime(this DateTime date)
{
var epoch = new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc);
return Convert.ToInt64((date - epoch).TotalSeconds);
}
请注意下面CodesInChaos的评论,上面的
FromUnixTime
返回一个带有DateTime
的Kind
是可以的,但是上面的Utc
更令人怀疑,因为它并不说明给定ToUnixTime
是哪种DateTime
。要允许date
的date
是Kind
或Utc
,请使用Local
:public static long ToUnixTime(this DateTime date)
{
var epoch = new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc);
return Convert.ToInt64((date.ToUniversalTime() - epoch).TotalSeconds);
}
ToUniversalTime
将ToUniversalTime
(或Local
)Unspecified
转换为DateTime
。如果您不希望在从DateTime移到epoch时创建epoch DateTime实例,也可以执行以下操作:
public static long ToUnixTime(this DateTime date)
{
return (date.ToUniversalTime().Ticks - 621355968000000000) / 10000000;
}
评论
仅当日期在Utc中时,ToUnixTime才能正常工作。添加支票,或将其转换。 (我个人更喜欢支票)
– CodesInChaos
2012年2月26日14:07
刚刚花了一个小时来弄清楚为什么这行不通。您需要以毫秒为单位而不是秒!
– KristianB
2012年9月13日14:14
@KristianB:自大纪元以来,“ Unix时间”通常是秒,而不是毫秒,尽管这些天我一直在仔细检查某人使用的定义。秒过去曾经足够好,并且以带符号的32位值为我们提供了The Epoch两侧的合理范围。 (这就是为什么在2038年1月19日凌晨3:14之后对某些人来说可能是个糟糕的时间...)由于我们通常能够抛出64位值(均为整数),因此使用毫秒是更现代的做法。和双精度IEEE-754)...
– T.J.拥挤者
13年1月20日在14:04
感谢您的代码。在创建纪元基础时,只是一个小小的建议:确保将毫秒值显式设置为0。即var epoch = new DateTime(1970,1,1,0 / * h * /,0 / * m * /,0 / * s * /,0 / * ms * /,DateTimeKind.Utc);如果未明确设置,则毫秒值似乎为1。这导致我的测试有些不一致。
–ctrlplusb
2014年4月28日13:20
您应该使用AddMilliseconds,并且应该使用Double NOT Float。否则,您将获得错误的时间。
–轴
16年3月31日在16:51
#4 楼
您实际上想要的是AddMilliseconds(毫秒),而不是秒。增加秒数将使您超出范围。评论
这是为什么? epochconverter.com它说您增加自1/1/970以来的秒数,而不是ms。
–杰米·Rytlewski
2014年6月5日17:51
如果您要从ms出发,则显然需要AddMillis,如果您要从几秒钟开始,则显然需要AddSeconds。
–鞋子
2014年7月17日在13:28
我有一个同样的问题,我使用秒数时一直超出范围。我尝试转换的Unix时间以毫秒为单位。我以为是几秒钟。我猜一些Unix时间以毫秒为单位。
–DoodleKana
15年5月13日在17:47
Unix时间通常以秒表示,但是0.001是有效的秒数(= 1 ms)。如有疑问,请使用最大可能的精度。
–他
17年7月10日在16:56
#5 楼
使用方法DateTimeOffset.ToUnixTimeMilliseconds()返回自1970-01-01T00:00:00.000Z以来经过的毫秒数。仅支持Framework 4.6或更高版本
var EPOCH = DateTimeOffset.UtcNow.ToUnixTimeMilliseconds();
DateTimeOffset.ToUnixTimeMilliseconds
另一种方法是使用以下
long EPOCH = DateTime.UtcNow.Ticks - new DateTime(1970, 1, 1,0,0,0,0).Ticks;
获取EPOCH仅几秒钟,您就可以使用
var Epoch = (int)(DateTime.UtcNow - new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc)).TotalSeconds;
,并使用以下方法将
Epoch
转换为DateTime
private DateTime Epoch2UTCNow(int epoch)
{
return new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc).AddSeconds(epoch);
}
评论
DateTime.Ticks-每个刻度是“一百纳秒”,使其成为需要记住的额外“东西”。如果省略两个.Ticks,则将从DateTime减法中获得一个不错的TimeSpan实例。
–user2864740
19年7月25日在17:21
#6 楼
如果您想获得更好的性能,可以使用此版本。public const long UnixEpochTicks = 621355968000000000;
public const long TicksPerMillisecond = 10000;
public const long TicksPerSecond = TicksPerMillisecond * 1000;
//[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static DateTime FromUnixTimestamp(this long unixTime)
{
return new DateTime(UnixEpochTicks + unixTime * TicksPerSecond);
}
从net471下的快速基准测试(BenchmarkDotNet)中,我得到以下编号:
Method | Mean | Error | StdDev | Scaled |
-------------- |---------:|----------:|----------:|-------:|
LukeH | 5.897 ns | 0.0897 ns | 0.0795 ns | 1.00 |
MyCustom | 3.176 ns | 0.0573 ns | 0.0536 ns | 0.54 |
比LukeH的版本快2倍(如果性能很重要)
这类似于DateTime在内部的工作方式。
#7 楼
// convert datetime to unix epoch seconds
public static long ToUnixTime(DateTime date)
{
var epoch = new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc);
return Convert.ToInt64((date.ToUniversalTime() - epoch).TotalSeconds);
}
应将ToUniversalTime()用于DateTime对象。
#8 楼
我使用以下扩展方法进行时代转换public static int GetEpochSeconds(this DateTime date)
{
TimeSpan t = DateTime.UtcNow - new DateTime(1970, 1, 1);
return (int)t.TotalSeconds;
}
public static DateTime FromEpochSeconds(this DateTime date, long EpochSeconds)
{
var epoch = new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc);
return epoch.AddSeconds(EpochSeconds);
}
#9 楼
目前,您只需使用DateTimeOffset.UtcNow.ToUnixTimeMilliseconds()
它就会以64位长的形式返回
#10 楼
不必担心使用毫秒或秒,只需执行以下操作: public static DateTime _ToDateTime(this long unixEpochTime)
{
DateTime epoch = new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc);
var date = epoch.AddMilliseconds(unixEpochTime);
if (date.Year > 1972)
return date;
return epoch.AddSeconds(unixEpochTime);
}
如果纪元时间以秒为单位,那么您将无法通过1972年添加毫秒。
#11 楼
如果您未使用4.6,则可能会有所帮助来源:System.IdentityModel.Tokens /// <summary>
/// DateTime as UTV for UnixEpoch
/// </summary>
public static readonly DateTime UnixEpoch = new DateTime(1970, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc);
/// <summary>
/// Per JWT spec:
/// Gets the number of seconds from 1970-01-01T0:0:0Z as measured in UTC until the desired date/time.
/// </summary>
/// <param name="datetime">The DateTime to convert to seconds.</param>
/// <remarks>if dateTimeUtc less than UnixEpoch, return 0</remarks>
/// <returns>the number of seconds since Unix Epoch.</returns>
public static long GetIntDate(DateTime datetime)
{
DateTime dateTimeUtc = datetime;
if (datetime.Kind != DateTimeKind.Utc)
{
dateTimeUtc = datetime.ToUniversalTime();
}
if (dateTimeUtc.ToUniversalTime() <= UnixEpoch)
{
return 0;
}
return (long)(dateTimeUtc - UnixEpoch).TotalSeconds;
}
评论
感谢JWT提供的示例。顺便说一下,要使用它,只需使用:using Microsoft.IdentityModel.Tokens; ... EpochTime.GetIntDate(dateTime);
– Liquide
19年8月6日在15:38
#12 楼
如果需要在不损失精度的情况下将包含UNIX time
的时间结构(秒,微秒)转换为DateTime
,请执行以下操作:DateTime _epochTime = new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc);
private DateTime UnixTimeToDateTime(Timeval unixTime)
{
return _epochTime.AddTicks(
unixTime.Seconds * TimeSpan.TicksPerSecond +
unixTime.Microseconds * TimeSpan.TicksPerMillisecond/1000);
}
#13 楼
从.Net 4.6及更高版本开始,请使用DateTimeOffset.Now.ToUnixTimeSeconds()#14 楼
这是我的解决方案:public long GetTime()
{
DateTime dtCurTime = DateTime.Now.ToUniversalTime();
DateTime dtEpochStartTime = Convert.ToDateTime("1/1/1970 0:00:00 AM");
TimeSpan ts = dtCurTime.Subtract(dtEpochStartTime);
double epochtime;
epochtime = ((((((ts.Days * 24) + ts.Hours) * 60) + ts.Minutes) * 60) + ts.Seconds);
return Convert.ToInt64(epochtime);
}
评论
这说明leap年和leap秒等吗?
–乔德雷尔
2012年8月22日13:41
为了扩展之前的评论,以下是一段简短的视频,解释了为什么时间很复杂以及为什么您不应该自己尝试做:youtube.com/watch?v=-5wpm-gesOY
–vmrob
15年7月19日在18:31
评论
除非我缺少任何东西,否则“纪元”只是特定计时计划的起点。示例包括1/1 / 0001、1 / 1/1970和1/1/2000。它更多是方案本身的属性,而不是方案本身(例如朱利安(Julian))。自纪元以来的时间是自UTC 1970年1月1日以来的秒数。
@Taylor这是Unix时间的纪元,也许是正确的,但这不是唯一有效的纪元。 Unix时间用户不应在这一点上感到困惑。
Dup,以及其他答案:stackoverflow.com/q/3354893/712526