it-roy-ru.com

Как я могу преобразовать метку времени Unix в DateTime и наоборот?

Этот пример кода есть, но затем он начинает говорить о проблемах миллисекунды/наносекунды.

Тот же вопрос на 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);
  }
}
647
Mark Ingram

Вот что вам нужно:

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

Или для Java (который отличается, потому что отметка времени указывается в миллисекундах, а не секундах):

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

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

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

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

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;
310
i3arnon

Отметка времени DateTime в UNIX:

public static double DateTimeToUnixTimestamp(DateTime dateTime)
{
    return (TimeZoneInfo.ConvertTimeToUtc(dateTime) - 
           new DateTime(1970, 1, 1, 0, 0, 0, 0, System.DateTimeKind.Utc)).TotalSeconds;
}
209
Dmitry Fedorkov

«UTC не меняется со сменой сезонов, но местное или гражданское время может измениться, если юрисдикция часового пояса соблюдает переход на летнее время (летнее время). Например, UTC опережает на 5 часов (то есть позже в тот же день) чем) по местному времени на восточном побережье Соединенных Штатов зимой, но на 4 часа вперед, когда там наблюдается переход на летнее время ».

Итак, это мой код:

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

Будьте осторожны, если вам нужна точность выше миллисекунд!

Методы .NET (v4.6) (например, FromUnixTimeMilliseconds ) не обеспечивают эту точность.

AddSeconds и AddMilliseconds также обрезают микросекунды в двойном размере.

Эти версии имеют высокую точность:

Unix -> DateTime

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

DateTime -> Unix

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;
}
20
Felix Keil

Смотрите 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);
    }
}
13
orad

В дополнение к ответу Скоттера, я недавно оказался в раздражающем сценарии, когда метки времени 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);
}
10
Chris Thoman

Преобразование времени в Unix впервые в .NET Framework 4.6.

Теперь вы можете легко преобразовывать значения даты и времени в типы .NET Framework и время Unix или из них. Это может быть необходимо, например, при преобразовании значений времени между клиентом JavaScript и сервером .NET. Следующие API были добавлены в структуру DateTimeOffset :

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

Я нашел правильный ответ, просто сравнив конверсию с 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;
5
n8CodeGuru
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 по мере необходимости.

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

// 1510396991

var dt = DateTimeOffset.FromUnixTimeSeconds(1510396991);

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

2
mesut

Тик Unix составляет 1 секунду (если я хорошо помню), а тик .NET - 100 наносекунд. 

Если у вас возникли проблемы с наносекундами, вы можете попробовать использовать AddTick (значение 10000000 *).

2
Luk

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

вы можете вызвать UnixTime.UnixTimeToDateTime (двойная дата-время)

0
madan

Из .net 4.6 вы можете сделать это:

var dateTime = DateTimeOffset.FromUnixTimeSeconds(unixDateTime).DateTime;
0
Yang Zhang