C#でUnix エポック時間をリアルタイムに変換するにはどうすればよいですか?(1970年1月1日以降のエポック)
C#でUnix エポック時間をリアルタイムに変換するにはどうすればよいですか?(1970年1月1日以降のエポック)
回答:
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);
AddXYZ
方法を使用します。
ネットの最新バージョン(V4.6)は、単に組み込みのUnixの時間の変換のためのサポートを追加します。これには、秒単位またはミリ秒単位で表される、Unixの時刻との両方が含まれます。
DateTimeOffset
:DateTimeOffset dateTimeOffset = DateTimeOffset.FromUnixTimeSeconds(1000);
DateTimeOffset
秒単位のUnix時間:long unixTimeStampInSeconds = dateTimeOffset.ToUnixTimeSeconds();
DateTimeOffset
:DateTimeOffset dateTimeOffset = DateTimeOffset.FromUnixTimeMilliseconds(1000000);
DateTimeOffset
ミリ秒単位のUnix時間:long unixTimeStampInMilliseconds= dateTimeOffset.ToUnixTimeMilliseconds();
注:これらのメソッドはとの間で変換を行いDateTimeOffset
ます。DateTime
表現を取得するには、DateTimeOffset.DateTime
プロパティを使用します。
DateTime dateTime = dateTimeOffset.UtcDateTime;
'DateTimeOffset' does not contain a definition for 'FromUnixTimeSeconds'
どのように解決しようとしていますか?
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
を返します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;
}
ToUnixTime
日付がUtcの場合にのみ正しく機能します。チェックを追加するか、変換します。(個人的には小切手を好む)
milliseconds
ません !!!
AddMilliseconds
あり、あなたはDouble NOT Floatを使用すべきです。そうしないと、間違った時間になってしまいます。
実際には、秒ではなくAddMilliseconds(ミリ秒)を使用します。秒を追加すると、範囲外の例外が発生します。
AddMillis
おり、あなたが数秒から始めているならあなたは明らかに望んでいるAddSeconds
。
より良いパフォーマンスが必要な場合は、このバージョンを使用できます。
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が内部で機能する方法に似ています。
メソッド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;
そして、変換するEpoch
にDateTime
は以下の方法で
private DateTime Epoch2UTCNow(int epoch)
{
return new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc).AddSeconds(epoch);
}
.Ticks
すると、DateTime減算から素敵なTimeSpanインスタンスが返されます。
エポック変換には次の拡張メソッドを使用します
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);
}
ミリ秒や秒の使用を心配しない場合は、次のようにします。
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年を過ぎてミリ秒を追加する方法はありません。
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;
}
using Microsoft.IdentityModel.Tokens; ... EpochTime.GetIntDate(dateTime);
あなたが変換する必要がある場合には体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);
}
.Net 4.6以降では、DateTimeOffset.Now.ToUnixTimeSeconds()を使用してください
これが私の解決策です:
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);
}