Bagaimana Anda mengubah waktu Unix ke waktu nyata dalam C #? (Epoch awal 1/1/1970)
Bagaimana Anda mengubah waktu Unix ke waktu nyata dalam C #? (Epoch awal 1/1/1970)
Jawaban:
Saya kira maksud Anda waktu Unix , yang didefinisikan sebagai jumlah detik sejak tengah malam (UTC) pada tanggal 1 Januari 1970.
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
metode yang tepat .
Versi terbaru .Net (v4.6) baru saja menambahkan dukungan bawaan untuk konversi waktu Unix. Itu termasuk ke dan dari waktu Unix yang diwakili oleh detik atau milidetik.
DateTimeOffset
:DateTimeOffset dateTimeOffset = DateTimeOffset.FromUnixTimeSeconds(1000);
DateTimeOffset
ke waktu Unix dalam detik:long unixTimeStampInSeconds = dateTimeOffset.ToUnixTimeSeconds();
DateTimeOffset
:DateTimeOffset dateTimeOffset = DateTimeOffset.FromUnixTimeMilliseconds(1000000);
DateTimeOffset
hingga waktu Unix dalam milidetik:long unixTimeStampInMilliseconds= dateTimeOffset.ToUnixTimeMilliseconds();
Catatan: Metode ini dikonversi ke dan dari DateTimeOffset
. Untuk mendapatkan DateTime
representasi cukup gunakan DateTimeOffset.DateTime
properti:
DateTime dateTime = dateTimeOffset.UtcDateTime;
'DateTimeOffset' does not contain a definition for 'FromUnixTimeSeconds'
Bagaimana saya bisa menyelesaikan ini?
Dengan semua kredit untuk LukeH, saya telah mengumpulkan beberapa metode ekstensi untuk mudah digunakan:
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);
}
Perhatikan komentar di bawah dari CodesInChaos bahwa di atas FromUnixTime
kembali sebuah DateTime
dengan Kind
dari Utc
yang baik-baik saja, tetapi di atas ToUnixTime
jauh lebih tersangka dalam yang tidak memperhitungkan apa DateTime
Mengingat date
adalah. Untuk memungkinkan date
's Kind
makhluk baik Utc
atau Local
, penggunaan 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
akan mengonversi Local
(atau Unspecified
) DateTime
ke Utc
.
jika Anda tidak ingin membuat contoh DateTime zaman ketika pindah dari DateTime ke zaman Anda juga dapat melakukan:
public static long ToUnixTime(this DateTime date)
{
return (date.ToUniversalTime().Ticks - 621355968000000000) / 10000000;
}
ToUnixTime
hanya berfungsi dengan benar jika tanggal dalam Utc. Tambahkan cek, atau ubah. (Secara pribadi saya lebih suka cek)
milliseconds
tidak detik !!!
AddMilliseconds
dan Anda harus menggunakan Double NOT Float. Kalau tidak, Anda akan berakhir dengan waktu yang salah.
Anda sebenarnya ingin AddMilliseconds (milidetik), bukan detik. Menambahkan detik akan memberi Anda pengecualian di luar rentang.
AddMillis
dan jika Anda mulai dari detik Anda jelas ingin AddSeconds
.
Jika Anda menginginkan kinerja yang lebih baik, Anda dapat menggunakan versi ini.
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);
}
Dari patokan cepat (BenchmarkDotNet) di bawah net471 saya mendapatkan nomor ini:
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 |
2x lebih cepat dari versi LukeH (jika kinerja mater)
Ini mirip dengan bagaimana DateTime bekerja secara internal.
Gunakan metode DateTimeOffset.ToUnixTimeMilliseconds () Ini mengembalikan jumlah milidetik yang telah berlalu sejak 1970-01-01T00: 00: 00.000Z.
Ini hanya didukung dengan Kerangka 4.6 atau lebih tinggi
var EPOCH = DateTimeOffset.UtcNow.ToUnixTimeMilliseconds();
Ini didokumentasikan dengan baik di sini DateTimeOffset.ToUnixTimeMilliseconds
Cara keluar lainnya adalah menggunakan yang berikut ini
long EPOCH = DateTime.UtcNow.Ticks - new DateTime(1970, 1, 1,0,0,0,0).Ticks;
Untuk mendapatkan EPOCH hanya dalam hitungan detik Anda dapat menggunakan
var Epoch = (int)(DateTime.UtcNow - new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc)).TotalSeconds;
dan konversikan Epoch
ke DateTime
dengan metode berikut
private DateTime Epoch2UTCNow(int epoch)
{
return new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc).AddSeconds(epoch);
}
.Ticks
, orang akan mendapatkan contoh TimeSpan yang bagus dari subtitle 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);
}
Harus menggunakan ToUniversalTime () untuk objek DateTime.
Saya menggunakan metode ekstensi berikut untuk konversi zaman
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);
}
Untuk tidak khawatir menggunakan milidetik atau detik, lakukan saja:
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);
}
Jika waktu dalam detik, maka tidak mungkin Anda bisa melewati tahun 1972 dengan menambahkan milidetik.
Jika Anda tidak menggunakan 4.6, ini dapat membantu Sumber: 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);
Dalam kasus Anda perlu mengkonversi struct timeval (detik, mikrodetik) mengandung UNIX time
ke DateTime
tanpa kehilangan presisi, ini adalah bagaimana:
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);
}
Sejak .Net 4.6 dan di atasnya, gunakan DateTimeOffset.Now.ToUnixTimeSeconds ()
Inilah solusi saya:
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);
}