C#でエポック時間をどのように変換しますか?


377

C#でUnix エポック時間をリアルタイムに変換するにはどうすればよいですか?(1970年1月1日以降のエポック)


1
私が何かを見逃していない限り、「エポック」は単に特定の計時スキームの原点です。例には、1/1 / 0001、1 / 1/1970、および1/1/2000が含まれます。これは、スキーム(たとえば、Julian)自体ではなく、スキームの属性の詳細です。
ボブカウフマン

8
エポックからの時間は、UTC 1970年1月1日からの秒数です。
テイラーリース

13
@テイラーそれはUNIX時代のエポックであり、おそらくそれは正しいですが、それだけが有効なエポックではありません。Unix時間のユーザーは、その点で混乱しないでください。
Joel Coehoorn、2010年

Dup

回答:


563

1970年1月1日の真夜中(UTC)からの秒数として定義されているUnix時間を意味していると思います。

public static DateTime FromUnixTime(long unixTime)
{
    return epoch.AddSeconds(unixTime);
}
private static readonly DateTime epoch = new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc);

74
これを正しく機能させるには、.AddSecondsを.AddMillisecondsに変更する必要がありました。正しい結果を得るには、数値が秒から来ているのかミリ秒から来ているのかを知る必要があります。たとえば、次の日付:1406310305188(2014年7月25日)。 epochconverter.comでは、変換結果を確認することもできます。
jrandomuser 2014

5
パラメーターの型をdoubleに変更するか(AddSecondsはdoubleを受け入れるため、doubleにダウンキャストするため)、引数の64ビットの精度のうち53ビットのみが保持されるという免責事項をメソッドの説明に追加する必要があります。
tomosius 2016年

6
@jrandomuser:Unixエポック時間は、伝統的にエポック以降の秒数で表されます。それ以来、エポック(たとえばJavaScript)からミリ秒を使用することが一般的になりましたが、古典的な定義は秒です。結論として、入力値が何であるか(秒、ミリ秒、ティックなど)を把握し、適切なAddXYZ方法を使用します。
TJクラウダー2017

最初にAddMillisecondsを試し、年がまだ1970の場合はAddSecondsを実行します。このようにして、ミリ秒や秒を気にすることなく、常に機能します。さらに、オーバーフロー例外を防ぐことができます。AddSecondsに大きな数を渡すとコードがクラッシュします
Tono Nam

213

ネットの最新バージョン(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;

1
私はこれを'DateTimeOffset' does not contain a definition for 'FromUnixTimeSeconds'どのように解決しようとしていますか?
ハッピーバード

@HappyBird .NET 4.6以上を使用していますか?
i3arnon 2017

同じこと-4.7.2、DateTimeOffsetのFromUnixTimeMillisecondsメソッドがない
Mikhail_Sam

わかった。新しいオブジェクトを作成する必要はありません。これは静的メソッドです。
Mikhail_Sam 2018年

一見すると、デフォルト値は少し混乱します。Bc 1000は、ミリ秒から秒に変換する係数です。
BluE

169

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はaのa DateTimeを返しますKindUtc、これは問題ありToUnixTimeませんがDateTime、指定された種類が何であるかを考慮していないため、上記ははるかに疑わしいものdateです。可能にするためdateKindビーイングのいずれかUtcまたはLocal、使用ToUniversalTime

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

ToUniversalTimeLocal(またはUnspecifiedDateTimeをに変換しUtcます。

DateTimeからエポックに移動するときにエポックDateTimeインスタンスを作成したくない場合は、次のようにすることもできます。

public static long ToUnixTime(this DateTime date)
{
    return (date.ToUniversalTime().Ticks - 621355968000000000) / 10000000;
}

6
ToUnixTime日付がUtcの場合にのみ正しく機能します。チェックを追加するか、変換します。(個人的には小切手を好む)
CodesInChaos

2
なぜこれが機能しないのかを理解するために、過去1時間過ごしただけです。数秒で作業する必要はありmilliseconds ません !!!
KristianB

7
@KristianB:「Unix時間」はエポック以降、伝統的にミリ秒ではなく秒ですが、最近は誰かが使用している定義を注意深くチェックしています。以前は秒で十分でしたが、符号付き32ビット値でThe Epochの両側に妥当な範囲を与えました。(そして、2038年1月19日の午前3時14分直後は、一部の人にとってGMTが悪い時間になるかもしれません...)ミリ秒を使用することは、64ビット値(両方とも整数)を日常的にスローできるため、より現代的な方法ですおよび倍精度IEEE-754)...
TJクラウダー

5
コードをありがとう。エポックベースを作成するときのほんの少しの推奨事項:ミリ秒の値を明示的に0に設定してください。つまり、var epoch = new DateTime(1970、1、1、0 / * h * /、0 / * m * /、0 / * s * /、0 /*ms*/、DateTimeKind.Utc); 明示的に設定しない場合、ミリ秒の値は1と表示されます。これにより、テストで不整合が発生しました。
ctrlplusb 2014

1
あなたは使用すべきでAddMillisecondsあり、あなたはDouble NOT Floatを使用すべきです。そうしないと、間違った時間になってしまいます。
Axel

25

実際には、秒ではなくAddMilliseconds(ミリ秒)を使用します。秒を追加すると、範囲外の例外が発生します。


何故ですか?epochconverter.com 970年1月1日からの秒数ではなく、msを追加すると表示されます。
Jamie R Rytlewski、2014年

あなたがmsから行くならあなたは明らかに望んでAddMillisおり、あなたが数秒から始めているならあなたは明らかに望んでいるAddSeconds
2014

秒を使用すると、範囲外に出続けたのと同じ問題がありました。私が変換しようとしたUNIX時間はミリ秒単位でした。秒だと思った。UNIX時間はミリ秒単位で測定されると思います。
DoodleKana

Unix時間は通常秒で表されますが、0.001は有効な秒数(= 1 ms)です。疑問がある場合は、可能な限り最大の精度を使用してください。
スコット

9

より良いパフォーマンスが必要な場合は、このバージョンを使用できます。

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が内部で機能する方法に似ています。


9

メソッド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;

秒だけでエポックを取得するには、使用できます

 var Epoch = (int)(DateTime.UtcNow - new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc)).TotalSeconds;

そして、変換するEpochDateTimeは以下の方法で

private DateTime Epoch2UTCNow(int epoch) 
{
    return new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc).AddSeconds(epoch); 
}

DateTime.Ticks-各ティックは「100ナノ秒」であり、覚えておく必要がある追加の「もの」になります。両方を省略.Ticksすると、DateTime減算から素敵なTimeSpanインスタンスが返されます。
user2864740

8
// 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);
}

DateTimeオブジェクトにはToUniversalTime()を使用する必要があります。


5

エポック変換には次の拡張メソッドを使用します

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

    }

2

ミリ秒や秒の使用を心配しない場合は、次のようにします。

    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年を過ぎてミリ秒を追加する方法はありません。


1

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

0

あなたが変換する必要がある場合には体timeval構造体を有する(秒、マイクロ秒)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);
}


-4

これが私の解決策です:

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

7
これはうるう年やうるう秒などを説明しますか?
Jodrell

1
以前のコメントに展開するには、ここでは時間が複雑になっている理由を説明する短いビデオだとなぜあなたはそれを自分でやってみるべきではありません。youtube.com/watch?v=-5wpm-gesOY
vmrob
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.