Bagaimana saya bisa mengkonversi Unix timestamp untuk DateTime dan sebaliknya?

Ada contoh ini kode, tapi kemudian ia mulai berbicara tentang milidetik / nanodetik masalah.

Pertanyaan yang sama di MSDN, Detik sejak Unix epoch di C#.

Ini adalah apa yang saya've punya sejauh ini:

public Double CreatedEpoch
{
  get
  {
    DateTime epoch = new DateTime(1970, 1, 1, 0, 0, 0, 0).ToLocalTime();
    TimeSpan span = (this.Created.ToLocalTime() - epoch);
    return span.TotalSeconds;
  }
  set
  {
    DateTime epoch = new DateTime(1970, 1, 1, 0, 0, 0, 0).ToLocalTime();
    this.Created = epoch.AddSeconds(value);
  }
}
Mengomentari pertanyaan (1)
Larutan

Berikut ini's apa yang anda butuhkan:

public static DateTime UnixTimeStampToDateTime( double unixTimeStamp )
{
    // Unix timestamp is seconds past epoch
    System.DateTime dtDateTime = new DateTime(1970,1,1,0,0,0,0,System.DateTimeKind.Utc);
    dtDateTime = dtDateTime.AddSeconds( unixTimeStamp ).ToLocalTime();
    return dtDateTime;
}

Atau, untuk Jawa (yang berbeda karena timestamp dalam milidetik, bukan detik):

public static DateTime JavaTimeStampToDateTime( double javaTimeStamp )
{
    // Java timestamp is milliseconds past epoch
    System.DateTime dtDateTime = new DateTime(1970,1,1,0,0,0,0,System.DateTimeKind.Utc);
    dtDateTime = dtDateTime.AddMilliseconds( javaTimeStamp ).ToLocalTime();
    return dtDateTime;
}
Komentar (12)

The versi terbaru .NET (v4.6) telah ditambahkan dukungan built-in untuk Unix waktu konversi. Yang termasuk ke dan dari Unix time yang diwakili oleh salah satu detik atau milidetik.

  • Unix waktu dalam detik untuk UTC DateTimeOffset:

DateTimeOffset dateTimeOffset = DateTimeOffset.FromUnixTimeSeconds(1000);
  • DateTimeOffset untuk Unix waktu dalam detik:

long unixTimeStampInSeconds = dateTimeOffset.ToUnixTimeSeconds();
  • Unix waktu dalam milidetik untuk UTC DateTimeOffset:

DateTimeOffset dateTimeOffset = DateTimeOffset.FromUnixTimeMilliseconds(1000000);
  • DateTimeOffset untuk Unix waktu dalam milidetik:

long unixTimeStampInMilliseconds = dateTimeOffset.ToUnixTimeMilliseconds();

Catatan: metode Ini mengkonversi ke dan dari UTC DateTimeOffset. Untuk mendapatkan DateTime representasi hanya menggunakan DateTimeOffset.UtcDateTime atau DateTimeOffset.LocalDateTime properties:

DateTime dateTime = dateTimeOffset.UtcDateTime;
Komentar (4)

DateTime untuk UNIX timestamp:

public static double DateTimeToUnixTimestamp(DateTime dateTime)
{
    return (TimeZoneInfo.ConvertTimeToUtc(dateTime) - 
           new DateTime(1970, 1, 1, 0, 0, 0, 0, System.DateTimeKind.Utc)).TotalSeconds;
}
Komentar (0)

Dari Wikipedia:

UTC tidak berubah dengan perubahan musim, tapi waktu setempat atau sipil waktu dapat berubah jika zona waktu yurisdiksi mengamati daylight saving time (waktu musim panas). Misalnya, waktu setempat, di pantai timur Amerika Serikat adalah lima jam di belakang UTC selama musim dingin, tapi empat jam di belakang saat daylight saving diamati ada.

Jadi, ini adalah kode saya:

TimeSpan span = (DateTime.UtcNow - new DateTime(1970, 1, 1, 0, 0, 0, 0,DateTimeKind.Utc));
double unixTime = span.TotalSeconds;
Komentar (1)

Hati-hati, jika anda membutuhkan presisi yang lebih tinggi dari milidetik!

.NET (v4.6) metode (misalnya FromUnixTimeMilliseconds) don't memberikan presisi ini.

AddSeconds dan AddMilliseconds juga memotong mikrodetik di ganda.

Versi ini memiliki presisi tinggi:

Unix -> DateTime

public static DateTime UnixTimestampToDateTime(double unixTime)
{
    DateTime unixStart = new DateTime(1970, 1, 1, 0, 0, 0, 0, System.DateTimeKind.Utc);
    long unixTimeStampInTicks = (long) (unixTime * TimeSpan.TicksPerSecond);
    return new DateTime(unixStart.Ticks + unixTimeStampInTicks, System.DateTimeKind.Utc);
}

DateTime -> Unix

public static double DateTimeToUnixTimestamp(DateTime dateTime)
{
    DateTime unixStart = new DateTime(1970, 1, 1, 0, 0, 0, 0, System.DateTimeKind.Utc);
    long unixTimeStampInTicks = (dateTime.ToUniversalTime() - unixStart).Ticks;
    return (double) unixTimeStampInTicks / TimeSpan.TicksPerSecond;
}
Komentar (4)

Lihat IdentityModel.EpochTimeExtensions

public static class EpochTimeExtensions
{
    /// 
    /// Converts the given date value to epoch time.
    /// 
    public static long ToEpochTime(this DateTime dateTime)
    {
        var date = dateTime.ToUniversalTime();
        var ticks = date.Ticks - new DateTime(1970, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc).Ticks;
        var ts = ticks / TimeSpan.TicksPerSecond;
        return ts;
    }

    /// 
    /// Converts the given date value to epoch time.
    /// 
    public static long ToEpochTime(this DateTimeOffset dateTime)
    {
        var date = dateTime.ToUniversalTime();
        var ticks = date.Ticks - new DateTimeOffset(1970, 1, 1, 0, 0, 0, TimeSpan.Zero).Ticks;
        var ts = ticks / TimeSpan.TicksPerSecond;
        return ts;
    }

    /// 
    /// Converts the given epoch time to a  with  kind.
    /// 
    public static DateTime ToDateTimeFromEpoch(this long intDate)
    {
        var timeInTicks = intDate * TimeSpan.TicksPerSecond;
        return new DateTime(1970, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc).AddTicks(timeInTicks);
    }

    /// 
    /// Converts the given epoch time to a UTC .
    /// 
    public static DateTimeOffset ToDateTimeOffsetFromEpoch(this long intDate)
    {
        var timeInTicks = intDate * TimeSpan.TicksPerSecond;
        return new DateTimeOffset(1970, 1, 1, 0, 0, 0, TimeSpan.Zero).AddTicks(timeInTicks);
    }
}
Komentar (2)

Untuk melengkapi ScottCher's jawaban, baru-baru ini saya menemukan diri saya dalam mengganggu skenario memiliki investasi detik dan milidetik cap waktu UNIX sewenang-wenang dicampur bersama-sama dalam sebuah set data input. Kode berikut tampaknya untuk menangani hal ini dengan baik:

static readonly DateTime UnixEpoch = new DateTime(1970, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc);
static readonly double MaxUnixSeconds = (DateTime.MaxValue - UnixEpoch).TotalSeconds;

public static DateTime UnixTimeStampToDateTime(double unixTimeStamp)
{
   return unixTimeStamp > MaxUnixSeconds
      ? UnixEpoch.AddMilliseconds(unixTimeStamp)
      : UnixEpoch.AddSeconds(unixTimeStamp);
}
Komentar (2)

Unix time konversi ini baru di .NET Framework 4.6.

Anda sekarang dapat dengan mudah mengkonversi nilai tanggal dan waktu ke atau dari .NET Framework jenis dan Unix waktu. Hal ini dapat diperlukan, misalnya, ketika mengkonversi nilai-nilai waktu antara JavaScript dan klien .NET server. Berikut ini Api telah ditambahkan ke DateTimeOffset struktur:

static DateTimeOffset FromUnixTimeSeconds(long seconds)
static DateTimeOffset FromUnixTimeMilliseconds(long milliseconds)
long DateTimeOffset.ToUnixTimeSeconds()
long DateTimeOffset.ToUnixTimeMilliseconds()
Komentar (3)

Saya menemukan jawaban yang tepat hanya dengan membandingkan konversi ke 1/1/1970 w/o waktu setempat penyesuaian;

DateTime date = new DateTime(2011, 4, 1, 12, 0, 0, 0);
DateTime epoch = new DateTime(1970, 1, 1, 0, 0, 0, 0);
TimeSpan span = (date - epoch);
double unixTime =span.TotalSeconds;
Komentar (0)
var dt = DateTime.Now; 
var unixTime = ((DateTimeOffset)dt).ToUnixTimeSeconds();

// 1510396991

var dt = DateTimeOffset.FromUnixTimeSeconds(1510396991);

// [11.11.2017 10:43:11 +00:00]

Komentar (0)
DateTime unixEpoch = DateTime.ParseExact("1970-01-01", "yyyy-MM-dd", System.Globalization.CultureInfo.InvariantCulture);
DateTime convertedTime = unixEpoch.AddMilliseconds(unixTimeInMillisconds);

Tentu saja, seseorang dapat membuat unixEpoch global statis, sehingga hanya perlu muncul sekali dalam proyek anda, dan satu dapat menggunakan AddSeconds jika UNIX waktu dalam detik.

Untuk pergi dengan cara lain:

double unixTimeInMilliseconds = timeToConvert.Subtract(unixEpoch).TotalMilliseconds;

Truncate untuk Int64 dan/atau menggunakan TotalSeconds yang diperlukan.

Komentar (0)

Unix tick adalah 1 detik (jika saya ingat dengan baik), dan .NET tick adalah 100 nanodetik.

Jika anda've telah menghadapi masalah dengan nanodetik, anda mungkin ingin mencoba menggunakan AddTick(10000000 * nilai).

Komentar (1)

Dari .net 4.6, anda dapat melakukan ini:

var dateTime = DateTimeOffset.FromUnixTimeSeconds(unixDateTime).DateTime;
Komentar (0)

Aku yang dibutuhkan untuk mengkonversi struct timeval (detik, mikrodetik) yang mengandung UNIX time untuk DateTime tanpa kehilangan presisi dan modern't menemukan jawabannya di sini jadi saya pikir saya hanya bisa menambahkan saya:

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);
}
Komentar (0)
System.DateTimeOffset.Now.ToUnixTimeSeconds()
Komentar (0)

Menulis sederhana ekstensi yang bekerja untuk kita. Jika ada yang terlihat untuk itu...

public static class DateTimeExtensions
{
    public static DateTime FromUnixTimeStampToDateTime(this string unixTimeStamp)
    {

        return DateTimeOffset.FromUnixTimeSeconds(long.Parse(unixTimeStamp)).UtcDateTime;
    }
}
Komentar (0)
public static class UnixTime
    {
        private static readonly DateTime Epoch = new DateTime(1970, 1, 1, 0, 0, 0, 0);

        public static DateTime UnixTimeToDateTime(double unixTimeStamp)
        {
            return Epoch.AddSeconds(unixTimeStamp).ToUniversalTime();
        }
    }

anda dapat menghubungi UnixTime.UnixTimeToDateTime(double datetime))

Komentar (0)

Untuk .NET 4.6 dan kemudian:

public static class UnixDateTime
{
    public static DateTimeOffset FromUnixTimeSeconds(long seconds)
    {
        if (seconds < -62135596800L || seconds > 253402300799L)
            throw new ArgumentOutOfRangeException("seconds", seconds, "");

        return new DateTimeOffset(seconds * 10000000L + 621355968000000000L, TimeSpan.Zero);
    }

    public static DateTimeOffset FromUnixTimeMilliseconds(long milliseconds)
    {
        if (milliseconds < -62135596800000L || milliseconds > 253402300799999L)
            throw new ArgumentOutOfRangeException("milliseconds", milliseconds, "");

        return new DateTimeOffset(milliseconds * 10000L + 621355968000000000L, TimeSpan.Zero);
    }

    public static long ToUnixTimeSeconds(this DateTimeOffset utcDateTime)
    {
        return utcDateTime.Ticks / 10000000L - 62135596800L;
    }

    public static long ToUnixTimeMilliseconds(this DateTimeOffset utcDateTime)
    {
        return utcDateTime.Ticks / 10000L - 62135596800000L;
    }

    [Test]
    public void UnixSeconds()
    {
        DateTime utcNow = DateTime.UtcNow;
        DateTimeOffset utcNowOffset = new DateTimeOffset(utcNow);

        long unixTimestampInSeconds = utcNowOffset.ToUnixTimeSeconds();

        DateTimeOffset utcNowOffsetTest = UnixDateTime.FromUnixTimeSeconds(unixTimestampInSeconds);

        Assert.AreEqual(utcNowOffset.Year, utcNowOffsetTest.Year);
        Assert.AreEqual(utcNowOffset.Month, utcNowOffsetTest.Month);
        Assert.AreEqual(utcNowOffset.Date, utcNowOffsetTest.Date);
        Assert.AreEqual(utcNowOffset.Hour, utcNowOffsetTest.Hour);
        Assert.AreEqual(utcNowOffset.Minute, utcNowOffsetTest.Minute);
        Assert.AreEqual(utcNowOffset.Second, utcNowOffsetTest.Second);
    }

    [Test]
    public void UnixMilliseconds()
    {
        DateTime utcNow = DateTime.UtcNow;
        DateTimeOffset utcNowOffset = new DateTimeOffset(utcNow);

        long unixTimestampInMilliseconds = utcNowOffset.ToUnixTimeMilliseconds();

        DateTimeOffset utcNowOffsetTest = UnixDateTime.FromUnixTimeMilliseconds(unixTimestampInMilliseconds);

        Assert.AreEqual(utcNowOffset.Year, utcNowOffsetTest.Year);
        Assert.AreEqual(utcNowOffset.Month, utcNowOffsetTest.Month);
        Assert.AreEqual(utcNowOffset.Date, utcNowOffsetTest.Date);
        Assert.AreEqual(utcNowOffset.Hour, utcNowOffsetTest.Hour);
        Assert.AreEqual(utcNowOffset.Minute, utcNowOffsetTest.Minute);
        Assert.AreEqual(utcNowOffset.Second, utcNowOffsetTest.Second);
        Assert.AreEqual(utcNowOffset.Millisecond, utcNowOffsetTest.Millisecond);
    }
}
Komentar (1)