Как вы конвертируете время эпохи в C #? - PullRequest
332 голосов
/ 21 мая 2010

Как конвертировать Unix время эпохи в реальное время в C #?(Начало эпохи 01.01.1970)

Ответы [ 11 ]

511 голосов
/ 21 мая 2010

Я предполагаю, что вы имеете в виду 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);
170 голосов
/ 07 октября 2014

последняя версия .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;
158 голосов
/ 21 октября 2011

С благодарностью 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 возвращает 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;
}
22 голосов
/ 20 марта 2012

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

8 голосов
/ 28 января 2018

Если вы хотите лучшую производительность, вы можете использовать эту версию.

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

Из быстрого теста (BenchmarkDotNet) под net471 я получаю этот номер:

        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 |

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

Это похоже на внутреннюю работу DateTime.

7 голосов
/ 13 марта 2012
// 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.

5 голосов
/ 31 октября 2015

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

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

    }
2 голосов
/ 29 мая 2019

Используйте метод 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;
0 голосов
/ 14 октября 2015

Если вы не используете 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;
    }    
0 голосов
/ 06 июня 2014

Если вам нужно преобразовать временную структуру (секунды, микросекунды), содержащую 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);
}
...