Как конвертировать время эпохи в C#?


Как конвертировать Unix эпоха времени в реальном времени в C#? (Эпоха начала 1/1/1970)

10 295

10 ответов:

Я полагаю, что вы имеете в виду Unix time, который определяется как количество секунд с полуночи (UTC) 1 января 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);

со всем кредитом 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 DateTime С Kind на Utc, это хорошо, но выше ToUnixTime гораздо более подозрительно в том, что не учитывает, что за DateTime данного date есть. Чтобы учесть date ' s 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 преобразует a Local (или Unspecified)DateTime до Utc.

если вы не хотите создавать экземпляр epoch DateTime при переходе от DateTime к epoch, вы также можете сделать:

public static long ToUnixTime(this DateTime date)
{
    return (date.ToUniversalTime().Ticks - 621355968000000000) / 10000000;
}

The последняя версия .Net (v4.6) просто добавлена встроенная поддержка преобразования времени Unix. Это включает в себя как время до, так и от Unix, представленное секундами или миллисекундами.

  • время Unix в секундах до DateTimeOffset:

DateTimeOffset dateTimeOffset = DateTimeOffset.FromUnixTimeSeconds(1000);
  • DateTimeOffset до времени Unix в секундах:

long unixTimeStampInSeconds = dateTimeOffset.ToUnixTimeSeconds();
  • Unix время в миллисекундах до DateTimeOffset:

DateTimeOffset dateTimeOffset = DateTimeOffset.FromUnixTimeMilliseconds(1000000);
  • DateTimeOffset время Unix в миллисекундах:

long unixTimeStampInMilliseconds= dateTimeOffset.ToUnixTimeMilliseconds();

примечание: эти методы преобразования DateTimeOffset. Чтобы получить DateTime представление просто использовать DateTimeOffset.DateTime свойства:

DateTime dateTime = dateTimeOffset.UtcDateTime;

вы на самом деле хотите добавить миллисекунды(миллисекунды), а не секунд. Добавление секунд даст вам исключение из диапазона.

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

следует использовать ToUniversalTime () для объекта DateTime.

Я использую следующие методы расширения для преобразования эпохи

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

из quick benchmark (BenchmarkDotNet) под net471 я получаю это число:

        Method |     Mean |     Error |    StdDev | Scaled |
-------------- |---------:|----------:|----------:|-------:|
 StackOverflow | 5.897 ns | 0.0897 ns | 0.0795 ns |   1.00 |
      MyCustom | 3.176 ns | 0.0573 ns | 0.0536 ns |   0.54 |

2x быстрее против версии LukeH (если производительность mater)

это похоже на то, как DateTime внутренне работает.

В случае, если вам нужно преобразовать timeval struct (секунды, микросекунды), содержащий UNIX time to 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);
}

Если вы не используете 4.6, это может помочь источник:

вот мое решение:

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