C#でUnixエポック時間をリアルタイムに変換するにはどうすればよいですか? (1970 年 1 月 1 日から始まるエポック)
14 に答える
2020年の更新
これはDateTimeOffsetで実行できます
DateTimeOffset dateTimeOffset = DateTimeOffset.FromUnixTimeSeconds(epochSeconds);
DateTimeOffset dateTimeOffset2 = DateTimeOffset.FromUnixTimeMilliseconds(epochMilliseconds);
DateTime
また、の代わりにオブジェクトが必要な場合は、プロパティDateTimeOffset
を呼び出すことができますDateTime
DateTime dateTime = dateTimeOffset.DateTime;
元の回答
1970年1月1日の真夜中(UTC)からの秒数として定義されるUnix時間を意味していると思います。
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);
}
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 からの以下のコメントに注意してください。上記は aを含む aをFromUnixTime
返しますが、これは問題ありませんが、上記は与えられたがどのようなものであるかを説明していないという点ではるかに疑わしいです。for が またはのいずれかであることを許可するには、次を使用します。DateTime
Kind
Utc
ToUnixTime
DateTime
date
date
Kind
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);
}
ToUniversalTime
Local
(またはUnspecified
)DateTime
を に変換しUtc
ます。
DateTime からエポックに移動するときにエポック DateTime インスタンスを作成したくない場合は、次のこともできます。
public static long ToUnixTime(this DateTime date)
{
return (date.ToUniversalTime().Ticks - 621355968000000000) / 10000000;
}
実際には、秒ではなく AddMilliseconds(ミリ秒) が必要です。秒を追加すると、範囲外の例外が発生します。
Unix エポックは、1970 年 1 月 1 日午前 0 時 (UTC 時間) から経過した秒数からうるう秒を引いたものです。これは、1970 年 1 月 1 日の午前 0 時に Unix 時間が 0 だったことを意味します。Unix エポックは、Unix 時間、POSIX 時間、または Unix タイムスタンプとも呼ばれます。
.Net Framework 4.6以降の場合DateTimeOffset.ToUnixTimeMilliseconds()メソッドを使用 してから経過したミリ秒数を返します1970-01-01T00:00:00.000Z
。
var EPOCH = DateTimeOffset.UtcNow.ToUnixTimeMilliseconds();
ここで十分に文書化されていますDateTimeOffset.ToUnixTimeMilliseconds
秒だけでエポックを取得するには、次を使用できます
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);
}
しかしそれ以来
Unix 時間の表現が符号付き 32 ビット数であるシステムでは、2038 年 1 月 19 日 UTC の 3:14:08 に発生する 231 - 1 秒後に表現が終了します。これは 2038 年問題と呼ばれ、32 ビット符号付き Unix 時刻がオーバーフローします。
EPOCH_2038_SAFEでない限り保存することをお勧めしint
ます
long EPOCH_2038_SAFE =
(long)(DateTime.UtcNow - new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc)).TotalSeconds;
さらに探している場合は、より多くのティック精度で以下を使用してください
long EPOCH = DateTime.UtcNow.Ticks - new DateTime(1970, 1, 1,0,0,0,0).Ticks;
より良いパフォーマンスが必要な場合は、このバージョンを使用できます。
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 が内部でどのように機能するかに似ています。
// 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() を使用する必要があります。
エポック変換には次の拡張メソッドを使用します
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);
}
精度を失わずに timeval 構造体 (秒、マイクロ秒) を変換する必要がある場合は、次のようにします。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);
}