Как преобразовать время эпохи в C#?
Как преобразовать Unix эпоха времени в режиме реального времени в C#? (Эпоха начала 1/1/1970)
10 ответов
Я полагаю, что вы имеете в виду Unix время, который определяется как количество секунд с полуночи (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
возвращает DateTime
С Kind
of 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
преобразует Local
(или Unspecified
) DateTime
до Utc
.
если вы не хотите создавать экземпляр epoch DateTime при переходе от DateTime к epoch, вы также можете сделать:
public static long ToUnixTime(this DateTime date)
{
return (date.ToUniversalTime().Ticks - 621355968000000000) / 10000000;
}
на последняя версия .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);
}
вот мое решение:
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);
}