كيف يمكنني تحويل الطابع الزمني لنظام Unix إلى DateTime والعكس؟

StackOverflow https://stackoverflow.com/questions/249760

سؤال

يوجد نموذج التعليمات البرمجية هذا، ولكنه يبدأ بعد ذلك في الحديث عن مشكلات المللي ثانية / النانو ثانية.

نفس السؤال موجود على MSDN ثواني منذ عصر Unix في C#.

هذا ما لدي حتى الآن:

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);
  }
}
هل كانت مفيدة؟

المحلول

وهنا هو ما تحتاج:

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

وأو لجاوا (الذي يختلف لأن الطابع الزمني في ميلي ثانية، وليس ثواني):

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

نصائح أخرى

ال أحدث إصدار من .NET (v4.6) أضاف دعمًا مدمجًا لتحويلات وقت Unix.يتضمن ذلك الوقت من وإلى Unix الذي يتم تمثيله إما بالثواني أو بالمللي ثانية.

  • وقت يونكس بالثواني إلى UTC DateTimeOffset:

DateTimeOffset dateTimeOffset = DateTimeOffset.FromUnixTimeSeconds(1000);
  • DateTimeOffset إلى وقت يونكس بالثواني:

long unixTimeStampInSeconds = dateTimeOffset.ToUnixTimeSeconds();
  • وقت Unix بالمللي ثانية إلى UTC DateTimeOffset:

DateTimeOffset dateTimeOffset = DateTimeOffset.FromUnixTimeMilliseconds(1000000);
  • DateTimeOffset إلى وقت Unix بالمللي ثانية:

long unixTimeStampInMilliseconds = dateTimeOffset.ToUnixTimeMilliseconds();

ملحوظة:تقوم هذه الطرق بالتحويل من وإلى UTC DateTimeOffset.للحصول على DateTime التمثيل ببساطة استخدم DateTimeOffset.UtcDateTime أو DateTimeOffset.LocalDateTime ملكيات:

DateTime dateTime = dateTimeOffset.UtcDateTime;

والتاريخ والوقت إلى UNIX الطابع الزمني:

public static double DateTimeToUnixTimestamp(DateTime dateTime)
{
    return (TimeZoneInfo.ConvertTimeToUtc(dateTime) - 
           new DateTime(1970, 1, 1, 0, 0, 0, 0, System.DateTimeKind.Utc)).TotalSeconds;
}
<اقتباس فقرة>   

وUTC لا تغيير مع تغير الفصول، ولكن بالتوقيت المحلي أو المدنية   قد تتغير الوقت إذا كان اختصاص المنطقة الزمنية يلاحظ الصيفي   الوقت (وقت الصيف). على سبيل المثال، التوقيت العالمي هو النتيجة 5 ساعات (أي،   في وقت لاحق من) بالتوقيت المحلي على الساحل الشرقي من الولايات المتحدة   الولايات خلال فصل الشتاء، ولكن 4 ساعات قبل بينما التوقيت الصيفي   لاحظ هناك.

وهكذا وهذا هو قانون بلدي:

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

كن حذرًا، إذا كنت بحاجة إلى دقة أعلى من المللي ثانية!

طرق .NET (v4.6) (على سبيل المثال فروميونيكس تايم ميلي ثانية) لا تقدم هذه الدقة.

أضف ثانية و أضف ميلي ثانية قم أيضًا بقطع الميكروثانية في المضاعفة.

تتميز هذه الإصدارات بدقة عالية:

يونيكس -> التاريخ والوقت

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

التاريخ والوقت -> يونكس

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

IdentityModel.EpochTimeExtensions

public static class EpochTimeExtensions
{
    /// <summary>
    /// Converts the given date value to epoch time.
    /// </summary>
    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;
    }

    /// <summary>
    /// Converts the given date value to epoch time.
    /// </summary>
    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;
    }

    /// <summary>
    /// Converts the given epoch time to a <see cref="DateTime"/> with <see cref="DateTimeKind.Utc"/> kind.
    /// </summary>
    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);
    }

    /// <summary>
    /// Converts the given epoch time to a UTC <see cref="DateTimeOffset"/>.
    /// </summary>
    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);
    }
}

لتكملة الإجابة ScottCher، وأنا في الآونة الأخيرة وجدت نفسي في السيناريو مزعج وجود كل ثانية، وميلي ثانية UNIX الطوابع مختلطة بشكل تعسفي معا في مجموعة البيانات المدخلة. يبدو التعليمات البرمجية التالية للتعامل مع هذا جيدا:

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

ويونكس وقت التحويل هو جديد في الإطار الصافي 4.6.

ويمكنك الآن أكثر سهولة تحويل قيم التاريخ والوقت أو من أنواع .NET Framework و وقت يونكس. وهذا يمكن أن يكون من الضروري، على سبيل المثال، عند تحويل قيم الوقت بين العميل والخادم جافا سكريبت .NET. تم إضافة واجهات برمجة التطبيقات التالية إلى DateTimeOffset هيكل :

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

ولقد وجدت الإجابة الصحيحة فقط من خلال مقارنة التحويل إلى 1/1/1970 ث / س تعديل بالتوقيت المحلي؛

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;
DateTime unixEpoch = DateTime.ParseExact("1970-01-01", "yyyy-MM-dd", System.Globalization.CultureInfo.InvariantCulture);
DateTime convertedTime = unixEpoch.AddMilliseconds(unixTimeInMillisconds);

وبطبيعة الحال، يمكن للمرء أن unixEpoch ثابت العالمية، لذلك يحتاج فقط لتظهر مرة واحدة في المشروع، ويمكن للمرء أن استخدام AddSeconds إذا كان الوقت UNIX بالثواني.

لتذهب في الاتجاه الآخر:

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

واقتطاع إلى Int64 و / أو استخدام TotalSeconds حسب الحاجة.

وهناك علامة يونكس 1 ثانية (إذا كنت أتذكر جيدا)، والقراد. NET هو 100 نانو ثانية.

إذا كنت قد تواجه مشاكل مع نانو ثانية، قد ترغب في محاولة استخدام AddTick (10000000 * القيمة).

var dt = DateTime.Now; 
var unixTime = ((DateTimeOffset)dt).ToUnixTimeSeconds();

و// 1510396991

var dt = DateTimeOffset.FromUnixTimeSeconds(1510396991);

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

ومن صافي 4.6، يمكنك القيام بذلك:

var dateTime = DateTimeOffset.FromUnixTimeSeconds(unixDateTime).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);
}
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();
        }
    }

ويمكنك الاتصال يونكس Time.Unix الوقت إلى التاريخ والوقت (التاريخ والوقت مزدوج))

ل. NET 4.6 والإصدارات الأحدث:

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);
    }
}
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top