網頁

.NET Framework 4.6新增Unix TimeStamp方法

.NET Framework 4.6新增Unix Time Stamp

skilltree課程

Timestamp(中文稱時戳、時間戳)是經常用於安全保護上的一種機制,例如每天上下班的打卡,就是一種保護勞資雙方的機制,卡打下去的那一刻的時間點是無法被偽造,用計算工時與工資。在網站資訊安全方面,例如近年流行的OAuth認證機制(facebook登入、google登入、github登入、Microsoft account登入…等第三方登入機制)中重要的Token,通常就會帶有Timestamp機制,以驗證Token的時效性。

Unix Time Stamp

TimeStamp很好,但他的格式並不好處理,我們看一下wiki上的範例:

  • Tue 01-01-2009 6:00
  • 2005-10-30 T 10:45 UTC
  • 2007-11-09 T 11:20 UTC
  • Sat Jul 23 02:16:57 2005
  • 12569537329
  • (1969-07-21 T 02:56 UTC) – first footstep on the Moon, "That's one small step for man, one giant leap for mankind"
  • 07:38, 11 December 2012 (UTC)

TimeStamp格式那麼多之外,在多國語系下,你可能還要自行先轉換為UTC (格林威治標準時間)時間。

在上述格式中,我們特別注意到一個12569537329數值,這是什麼東西?這種格式稱Unix Time,它是一種把時間轉換為數值的方式,它以1970-01-01 T 00:00 UTC為基準,每秒加 1 方式計算,如果是在基準點之前,就每秒 -1 方式計算。例如,我們把上述 Unix Time 放到http://www.unixtimestamp.com/進行轉換:

Timestamp Converter

就能還原成特定的時間點。因為數值的特性直覺、簡單、好處理,所以 Unix time 常被拿來做 Timestamp 使用。

.NET Framework 4.5之前時戳處理

在 .NET Framework 4.5 之前,時間相關結構型別並無提供 Unit Time Stamp 處理方法,如果有這方面的需求只能自己動手實作…不,是請G神幫忙,我下"C# 時戳"第一名是好友 Demo 編號 92 - 將時間轉換成timeStamp 的文章,以下是他實作版本:

DateTime to TimeStamp

  double timeStamp = DateTime.UtcNow.AddHours(8).Subtract(new DateTime(1970, 1, 1)).TotalSeconds; 
 

TimeStamp to DateTime

   DateTime gtm = (new DateTime(1970, 1, 1)).AddSeconds(Convert.ToInt32(timeStamp)); 
 

以下是我專案內的實作方式也給各位參考看看:

public static class UnixDateTime
{
    //Unix起始時間
    private static DateTime BaseTime = new DateTime(1970, 1, 1);

    /// <summary>
    /// 轉換UNIX時戳格式為C#的DateTime格式
    /// </summary>
    /// <param name="timeStamp">UNIX時戳</param>
    /// <returns>C#的DateTme格式</returns>
    public static DateTime Get(long timeStamp)
    {
        return BaseTime.AddTicks((timeStamp + 8 * 60 * 60) * 10000000);
    }

    /// <summary>
    /// 轉換UNIX時戳格式為C#的DateTime格式
    /// </summary>
    /// <param name="timeStamp">UNIX時戳</param>
    /// <returns>C#的DateTme格式</returns>
    public static DateTime Get(string timeStamp)
    {
        return Get(long.Parse(timeStamp));
    }

    /// <summary>
    /// 轉換C#的DateTime格式為UNIX時戳格式
    /// </summary>
    /// <param name="dateTime">DateTime物件</param>
    /// <returns>UNIX時戳格式</returns>
    public static long GetUNIX(DateTime dateTime)
    {
        return (dateTime.Ticks - BaseTime.Ticks) / 10000000 - 8 * 60 * 60;
    }
}
 

我其實只是多做了個字串轉數值的多載。

.NET Framework 4.6 的 Unix Time 轉換支援

.NET Framework 4.6 開始支援 Unix Time 的轉換。不過這些方法並不是在 DateTime 結構型別之內,而是在 DateTimeOffSet 結構型別之內。

.ToUnixTimeSeconds()

傳回自 1970-01-01T00:00:00Z (1970 年 1 月 1 日上午 12:00 UTC)以來所經過的秒數。

  DateTimeOffset.Now.ToUnixTimeSeconds();
 
linqpad - ToUnixTimeSeconds

.ToUnixTimeMilliseconds()

傳回自 1970-01-01T00:00:00Z (1970 年 1 月 1 日上午 12:00 UTC) 以來所經過的毫秒數。

  DateTimeOffset.Now.ToUnixTimeMilliseconds();
 
linqpad - ToUnixTimeMilliseconds

.FromUnixTimeSeconds()

將轉換 Unix 時間(表示自 1970-01-01T00:00:00Z (1970 年 1 月 1 日上午 12:00 UTC)以來所經過的秒數)至DateTimeOffset值。

  DateTimeOffset.FromUnixTimeSeconds(unixTime);
 
linqpad - FromUnixTimeSeconds

.FromUnixTimeMilliseconds()

將轉換 Unix 時間(以表示自 1970-01-01T00:00:00Z (1970 年 1 月 1 日上午 12:00 UTC)以來所經過的毫秒數)至 DateTimeOffset值。

  DateTimeOffset.FromUnixTimeMilliseconds(unixTime);
 
linqpad - FromUnixTimeMilliseconds

.NET Framework 4.6提供全新四組 Unix Time 的轉換方法,並提供更細緻的毫秒時戳,底層全部會自動轉換為 UTC (格林威治標準時間)來計算。

Timestamp 本身的唯一性讓它的應用面很廣泛,在數十年的發展後,.NET Framework 終於在 4.6 的版本支援 Unix Time 功能(為了跨平台?.NET Core?)。不過唯一小小的限制也是在那 .NET Framework 4.6 上面。

.net framework targetFramework

1 則留言:

  1. 感謝分享,新的專案應該都有4.6以上
    不過舊的專案麻………就多花點功夫轉換囉

    回覆刪除

感謝您的留言,如果我的文章你喜歡或對你有幫助,按個「讚」或「分享」它,我會很高興的。