Как конвертировать время эпохи в C#?
Как конвертировать Unix эпоха времени в реальном времени в C#? (Эпоха начала 1/1/1970)
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
возвращает aDateTime
СKind
наUtc
, это хорошо, но вышеToUnixTime
гораздо более подозрительно в том, что не учитывает, что заDateTime
данногоdate
есть. Чтобы учестьdate
' sKind
или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
преобразует aLocal
(или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
toDateTime
не теряя точности, вот как: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 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); }