2008-10-30 107 views
552

有這個示例代碼,但它開始談論毫秒/納秒問題。如何將Unix時間戳轉換爲DateTime,反之亦然?

同樣的問題在MSDN上,Seconds since the Unix epoch in C#

這是我到目前爲止有:

public Double CreatedEpoch 
{ 
    get 
    { 
    DateTime epoch = new DateTime(1970, 1, 1, 0, 0, 0, 0).ToLocalTime(); 
    TimeSpan span = (this.Created.ToLocalTime() - epoch); 
    return span.TotalSeconds; 
    } 
    set 
    { 
    DateTime epoch = new DateTime(1970, 1, 1, 0, 0, 0, 0).ToLocalTime(); 
    this.Created = epoch.AddSeconds(value); 
    } 
} 
+61

即將發佈的** .NET 4.6 **(將在今年晚些時候發佈)引入了對此的支持。請參見[`DateTimeOffset.FromUnixTimeSeconds`](https://msdn.microsoft.com/zh-cn/library/system.datetimeoffset.fromunixtimeseconds.aspx)和[`DateTimeOffset.ToUnixTimeSeconds`](https://msdn.microsoft.com/zh-cn/ com/en-us/library/system.datetimeoffset.tounixtimeseconds.aspx)方法。還有一些毫秒級的unix-time方法。 – 2015-05-05 09:29:29

回答

773

這裏有您需要什麼:

public static DateTime UnixTimeStampToDateTime(double unixTimeStamp) 
{ 
    // Unix timestamp is seconds past epoch 
    System.DateTime dtDateTime = new DateTime(1970,1,1,0,0,0,0,System.DateTimeKind.Utc); 
    dtDateTime = dtDateTime.AddSeconds(unixTimeStamp).ToLocalTime(); 
    return dtDateTime; 
} 

或者,爲Java(這是不同的,因爲時間戳是以毫秒爲單位,而不是秒):

public static DateTime JavaTimeStampToDateTime(double javaTimeStamp) 
{ 
    // Java timestamp is milliseconds past epoch 
    System.DateTime dtDateTime = new DateTime(1970,1,1,0,0,0,0,System.DateTimeKind.Utc); 
    dtDateTime = dtDateTime.AddMilliseconds(javaTimeStamp).ToLocalTime(); 
    return dtDateTime; 
} 
+3

AddSeconds對於小於0.1毫秒的值(iirc) – Luk 2008-11-03 17:32:40

+0

@Luk好像並沒有很好的表現,許多DateTime/TimeSpan方法都是[莫名其妙的亞毫秒級的受損](http://stackoverflow.com/questions/4672359/why-do-timespan-fromsecondsdouble-round-to-milliseconds)... – 2011-04-15 20:36:59

+4

Windows中的時間由HAL處理,並且在1ms到15ms範圍內接近精確。如果有人感興趣,可以在第112頁的[Windows Internals](http://shop.oreilly.com/product/0790145305930.do)中找到更多信息。 – 2012-04-13 14:59:30

2

一種UNIX滴答爲1秒(如果我記得很清楚),以及.NET刻度是100  納秒。

如果您遇到納秒級的問題,您可能需要嘗試使用AddTick(10000000 *值)。

+3

Unix是歷時數秒 - 這是1/1/70。 – ScottCher 2008-10-30 14:44:16

4

我找到了正確的答案只是通過比較轉換到1/1/1970 w/o本地時間調整;

DateTime date = new DateTime(2011, 4, 1, 12, 0, 0, 0); 
DateTime epoch = new DateTime(1970, 1, 1, 0, 0, 0, 0); 
TimeSpan span = (date - epoch); 
double unixTime =span.TotalSeconds; 
199

日期時間到UNIX時間戳:

public static double DateTimeToUnixTimestamp(DateTime dateTime) 
{ 
    return (TimeZoneInfo.ConvertTimeToUtc(dateTime) - 
      new DateTime(1970, 1, 1, 0, 0, 0, 0, System.DateTimeKind.Utc)).TotalSeconds; 
} 
44

「UTC不隨季節的變化而變化,但如果一個時區管轄實行夏令時,本地時間或民用時間可能會改變(夏令時)例如,UTC在冬季的美國東海岸當地時間前5小時(即當天晚些時候),但是在4小時之前,而在那裏觀察到夏令時。「

所以這是我的代碼:

TimeSpan span = (DateTime.UtcNow - new DateTime(1970, 1, 1, 0, 0, 0, 0,DateTimeKind.Utc)); 
double unixTime = span.TotalSeconds; 
8

爲了補充ScottCher的答案,我最近發現自己在兼具秒和毫秒UNIX時間戳在任意輸入數據集混合在一起的惱人場景。下面的代碼似乎很好地處理這個問題:

static readonly DateTime UnixEpoch = new DateTime(1970, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc); 
static readonly double MaxUnixSeconds = (DateTime.MaxValue - UnixEpoch).TotalSeconds; 

public static DateTime UnixTimeStampToDateTime(double unixTimeStamp) 
{ 
    return unixTimeStamp > MaxUnixSeconds 
     ? UnixEpoch.AddMilliseconds(unixTimeStamp) 
     : UnixEpoch.AddSeconds(unixTimeStamp); 
} 
1

我需要轉換timeval struct(秒,微秒)含UNIX timeDateTime不失精準,所以我想我只是想補充我的還沒有找到答案在這裏:

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); 
} 
14

要小心,如果你需要精度高於毫秒! (例如,FromUnixTimeMilliseconds)不提供此精度。

AddSecondsAddMilliseconds也切斷在雙微秒。

這些版本具有精度高:

的Unix - >日期時間

public static DateTime UnixTimestampToDateTime(double unixTime) 
{ 
    DateTime unixStart = new DateTime(1970, 1, 1, 0, 0, 0, 0, System.DateTimeKind.Utc); 
    long unixTimeStampInTicks = (long) (unixTime * TimeSpan.TicksPerSecond); 
    return new DateTime(unixStart.Ticks + unixTimeStampInTicks, System.DateTimeKind.Utc); 
} 

日期時間 - > Unix的

public static double DateTimeToUnixTimestamp(DateTime dateTime) 
{ 
    DateTime unixStart = new DateTime(1970, 1, 1, 0, 0, 0, 0, System.DateTimeKind.Utc); 
    long unixTimeStampInTicks = (dateTime.ToUniversalTime() - unixStart).Ticks; 
    return (double) unixTimeStampInTicks/TimeSpan.TicksPerSecond; 
} 
3
DateTime unixEpoch = DateTime.ParseExact("1970-01-01", "yyyy-MM-dd", System.Globalization.CultureInfo.InvariantCulture); 
DateTime convertedTime = unixEpoch.AddMilliseconds(unixTimeInMillisconds); 

當然,一個可以讓unixEpoch全局靜態,因此它只需要在項目中出現一次,如果UNIX時間以秒爲單位,則可以使用AddSeconds

爲了走另一條路:

double unixTimeInMilliseconds = timeToConvert.Subtract(unixEpoch).TotalMilliseconds; 

截斷爲Int64的和/或使用TotalSeconds需要。

219

latest version of .NET (v4.6)增加了對Unix時間轉換的內置支持。這包括來自和來自Unix時間的時間,以秒或毫秒錶示。

  • Unix時間,以秒爲DateTimeOffset

DateTimeOffset dateTimeOffset = DateTimeOffset.FromUnixTimeSeconds(1000); 
  • DateTimeOffset到Unix時間(秒):

long unixTimeStampInSeconds = dateTimeOffset.ToUnixTimeSeconds(); 
  • Unix時間以毫秒爲單位DateTimeOffset

DateTimeOffset dateTimeOffset = DateTimeOffset.FromUnixTimeMilliseconds(1000000); 
  • DateTimeOffset爲Unix時間(毫秒):

long unixTimeStampInMilliseconds= dateTimeOffset.ToUnixTimeMilliseconds(); 

注:這些方法轉換,並從DateTimeOffset。爲了得到一個DateTime表示只要使用DateTimeOffset.DateTime屬性:

DateTime dateTime = dateTimeOffset.UtcDateTime; 
12

IdentityModel.EpochTimeExtensions

public static class EpochTimeExtensions 
{ 
    /// <summary> 
    /// Converts the given date value to epoch time. 
    /// </summary> 
    public static long ToEpochTime(this DateTime dateTime) 
    { 
     var date = dateTime.ToUniversalTime(); 
     var ticks = date.Ticks - new DateTime(1970, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc).Ticks; 
     var ts = ticks/TimeSpan.TicksPerSecond; 
     return ts; 
    } 

    /// <summary> 
    /// Converts the given date value to epoch time. 
    /// </summary> 
    public static long ToEpochTime(this DateTimeOffset dateTime) 
    { 
     var date = dateTime.ToUniversalTime(); 
     var ticks = date.Ticks - new DateTimeOffset(1970, 1, 1, 0, 0, 0, TimeSpan.Zero).Ticks; 
     var ts = ticks/TimeSpan.TicksPerSecond; 
     return ts; 
    } 

    /// <summary> 
    /// Converts the given epoch time to a <see cref="DateTime"/> with <see cref="DateTimeKind.Utc"/> kind. 
    /// </summary> 
    public static DateTime ToDateTimeFromEpoch(this long intDate) 
    { 
     var timeInTicks = intDate * TimeSpan.TicksPerSecond; 
     return new DateTime(1970, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc).AddTicks(timeInTicks); 
    } 

    /// <summary> 
    /// Converts the given epoch time to a UTC <see cref="DateTimeOffset"/>. 
    /// </summary> 
    public static DateTimeOffset ToDateTimeOffsetFromEpoch(this long intDate) 
    { 
     var timeInTicks = intDate * TimeSpan.TicksPerSecond; 
     return new DateTimeOffset(1970, 1, 1, 0, 0, 0, TimeSpan.Zero).AddTicks(timeInTicks); 
    } 
} 
-1

對於.NET 4。6及更高版本:

public static class UnixDateTime 
{ 
    public static DateTimeOffset FromUnixTimeSeconds(long seconds) 
    { 
     if (seconds < -62135596800L || seconds > 253402300799L) 
      throw new ArgumentOutOfRangeException("seconds", seconds, ""); 

     return new DateTimeOffset(seconds * 10000000L + 621355968000000000L, TimeSpan.Zero); 
    } 

    public static DateTimeOffset FromUnixTimeMilliseconds(long milliseconds) 
    { 
     if (milliseconds < -62135596800000L || milliseconds > 253402300799999L) 
      throw new ArgumentOutOfRangeException("milliseconds", milliseconds, ""); 

     return new DateTimeOffset(milliseconds * 10000L + 621355968000000000L, TimeSpan.Zero); 
    } 

    public static long ToUnixTimeSeconds(this DateTimeOffset utcDateTime) 
    { 
     return utcDateTime.Ticks/10000000L - 62135596800L; 
    } 

    public static long ToUnixTimeMilliseconds(this DateTimeOffset utcDateTime) 
    { 
     return utcDateTime.Ticks/10000L - 62135596800000L; 
    } 

    [Test] 
    public void UnixSeconds() 
    { 
     DateTime utcNow = DateTime.UtcNow; 
     DateTimeOffset utcNowOffset = new DateTimeOffset(utcNow); 

     long unixTimestampInSeconds = utcNowOffset.ToUnixTimeSeconds(); 

     DateTimeOffset utcNowOffsetTest = UnixDateTime.FromUnixTimeSeconds(unixTimestampInSeconds); 

     Assert.AreEqual(utcNowOffset.Year, utcNowOffsetTest.Year); 
     Assert.AreEqual(utcNowOffset.Month, utcNowOffsetTest.Month); 
     Assert.AreEqual(utcNowOffset.Date, utcNowOffsetTest.Date); 
     Assert.AreEqual(utcNowOffset.Hour, utcNowOffsetTest.Hour); 
     Assert.AreEqual(utcNowOffset.Minute, utcNowOffsetTest.Minute); 
     Assert.AreEqual(utcNowOffset.Second, utcNowOffsetTest.Second); 
    } 

    [Test] 
    public void UnixMilliseconds() 
    { 
     DateTime utcNow = DateTime.UtcNow; 
     DateTimeOffset utcNowOffset = new DateTimeOffset(utcNow); 

     long unixTimestampInMilliseconds = utcNowOffset.ToUnixTimeMilliseconds(); 

     DateTimeOffset utcNowOffsetTest = UnixDateTime.FromUnixTimeMilliseconds(unixTimestampInMilliseconds); 

     Assert.AreEqual(utcNowOffset.Year, utcNowOffsetTest.Year); 
     Assert.AreEqual(utcNowOffset.Month, utcNowOffsetTest.Month); 
     Assert.AreEqual(utcNowOffset.Date, utcNowOffsetTest.Date); 
     Assert.AreEqual(utcNowOffset.Hour, utcNowOffsetTest.Hour); 
     Assert.AreEqual(utcNowOffset.Minute, utcNowOffsetTest.Minute); 
     Assert.AreEqual(utcNowOffset.Second, utcNowOffsetTest.Second); 
     Assert.AreEqual(utcNowOffset.Millisecond, utcNowOffsetTest.Millisecond); 
    } 
} 
5

Unix時間轉換在.NET Framework 4.6中是新增功能。

現在,您可以更輕鬆地將日期和時間值轉換爲.NET Framework類型和Unix時間。例如,在JavaScript客戶端和.NET服務器之間轉換時間值時,這可能是必需的。 DateTimeOffset structure已添加以下API:

static DateTimeOffset FromUnixTimeSeconds(long seconds) 
static DateTimeOffset FromUnixTimeMilliseconds(long milliseconds) 
long DateTimeOffset.ToUnixTimeSeconds() 
long DateTimeOffset.ToUnixTimeMilliseconds() 
相關問題