Вот этот пример кода, но затем он начинает говорить о проблемах миллисекунды / наносекунды.
Тот же вопрос по 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);
}
}





Тик Unix составляет 1 секунду (если я хорошо помню), а тик .NET - 100 наносекунд.
Если у вас возникли проблемы с наносекундами, вы можете попробовать использовать AddTick (значение 10000000 *).
Unix - это секунда прошедшей эпохи - 1/1/70.
Вот что вам понадобится:
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;
}
AddSeconds, похоже, не очень хорошо работает для значений меньше 0,1 миллисекунды (iirc)
@Luk да, несколько методов DateTime / TimeSpan - это необъяснимо субмиллисекундное нарушение ...
Время в Windows обрабатывается HAL и с точностью до 1–15 мс. Более подробная информация доступна в Внутреннее устройство Windows на странице 112, если кому-то интересно.
Этот ответ рискует сократить секунды ... Двойное число - это плавающее число. Аргумент должен иметь вид int / long / etc.
Эти методы должны принимать long или int, а не double. Кроме того, для меток времени Java нет необходимости делить на 1000 и округлять. Вобще dtDateTime.AddMilliseconds(javaTimeStamp).ToLocalTime();
Вы просто пропустили «наоборот»? Как преобразовать DateTime в метку времени?
Для .NET Framework 4.6 и выше теперь есть static DateTimeOffset.FromUnixMilliseconds и DateTimeOffset.ToUnixMilliseconds.
System.DateTime dtDateTime = новый DateTime.MinValue; должно быть достаточно.
Лучший способ выполнить вычисления без ошибок с плавающей запятой - это unixEpoch.AddTicks( TimeSpan.TicksPerSecond * seconds ).
Я нашел правильный ответ, просто сравнив преобразование с 01.01.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;
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;
}
От Википедия:
UTC does not change with a change of seasons, but local time or civil time may change if a time zone jurisdiction observes daylight saving time (summer time). For example, local time on the east coast of the United States is five hours behind UTC during winter, but four hours behind while daylight saving is observed there.
Итак, это мой код:
TimeSpan span = (DateTime.UtcNow - new DateTime(1970, 1, 1, 0, 0, 0, 0,DateTimeKind.Utc));
double unixTime = span.TotalSeconds;
но это возвращает двойной, я думаю, нужно забрасывать долго?
Чтобы дополнить ответ Скотта Чера, я недавно столкнулся с раздражающим сценарием, когда временные метки 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);
}
Будьте осторожны, когда не используете аргумент DateTimeKind, поскольку сконструированный DateTime будет соответствовать местному времени компьютера (спасибо за код, Крис)!
Будьте осторожны - это не будет работать для временных меток unix для дат до 11 января 1978 года, если они представлены в миллисекундах. Метка даты unix 253324800 (секунд) дает правильную дату 11.01.1978, тогда как миллисекундное представление 253324800000 дает дату 18.07.9997. Возможно, это сработало для вашего набора данных, но это не общее решение.
Мне нужно было преобразовать временная структура (секунды, микросекунды), содержащий 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);
}
Будьте осторожны, если вам нужна точность выше миллисекунд!
Методы .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;
}
Это правильный ответ. Другие получают неправильный часовой пояс при преобразовании обратно из метки времени.
для DateTime-> Java просто [код] return (long) unixTimeStampInTicks / TimeSpan.TicksPerMilliSecond; [/код]
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 по мере необходимости.
последняя версия .NET (v4.6) добавил встроенную поддержку преобразования времени Unix. Это включает время как до, так и от Unix, представленное секундами или миллисекундами.
DateTimeOffset:DateTimeOffset dateTimeOffset = DateTimeOffset.FromUnixTimeSeconds(1000);
DateTimeOffset в Unix время в секундах:long unixTimeStampInSeconds = dateTimeOffset.ToUnixTimeSeconds();
DateTimeOffset:DateTimeOffset dateTimeOffset = DateTimeOffset.FromUnixTimeMilliseconds(1000000);
DateTimeOffset в Unix время в миллисекундах:long unixTimeStampInMilliseconds = dateTimeOffset.ToUnixTimeMilliseconds();
Примечание. Эти методы конвертируют в формат UTC DateTimeOffset и обратно. Чтобы получить представление DateTime, просто используйте свойства DateTimeOffset.UtcDateTime или DateTimeOffset.LocalDateTime:
DateTime dateTime = dateTimeOffset.UtcDateTime;
Это не переводит время в местное время. Вы получите UTC, если используете DateTimeOffset.FromUnixTimeSeconds ().
@BerenddeBoer Вы можете использовать ToLocalTime, если хотите.
Чтобы узнать текущее время, вы можете использовать long unixMilliseconds = DateTimeOffset.Now.ToUnixTimeMilliseconds();
Абсолютно качественный ответ.
См. 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);
}
}
Это хорошо, но я бы предложил небольшое изменение: использование типа long следует изменить на Int32 или int. «Длинный» подразумевает значительную точность, но это не так. Вся математика точна только до 1 секунды, поэтому Int32 будет более намекающим на то, что вы ожидаете от метки времени Unix.
Я думаю, это связано с тем, что DateTime.Ticks является Int64 (длинным), поэтому они избегают лишнего неконтролируемого приведения.
Для .NET 4.6 и более поздних версий:
public static class UnixDateTime
{
public static DateTimeOffset FromUnixTimeSeconds(long seconds)
{
if (seconds < -62135596800L || seconds > 253402300799L)
throw new ArgumentOutOfRangeException("seconds", seconds, "");
return new DateTimeOffset(seconds * 10000000L + 621355968000000000L, TimeSpan.Zero);
}
public static DateTimeOffset FromUnixTimeMilliseconds(long milliseconds)
{
if (milliseconds < -62135596800000L || milliseconds > 253402300799999L)
throw new ArgumentOutOfRangeException("milliseconds", milliseconds, "");
return new DateTimeOffset(milliseconds * 10000L + 621355968000000000L, TimeSpan.Zero);
}
public static long ToUnixTimeSeconds(this DateTimeOffset utcDateTime)
{
return utcDateTime.Ticks / 10000000L - 62135596800L;
}
public static long ToUnixTimeMilliseconds(this DateTimeOffset utcDateTime)
{
return utcDateTime.Ticks / 10000L - 62135596800000L;
}
[Test]
public void UnixSeconds()
{
DateTime utcNow = DateTime.UtcNow;
DateTimeOffset utcNowOffset = new DateTimeOffset(utcNow);
long unixTimestampInSeconds = utcNowOffset.ToUnixTimeSeconds();
DateTimeOffset utcNowOffsetTest = UnixDateTime.FromUnixTimeSeconds(unixTimestampInSeconds);
Assert.AreEqual(utcNowOffset.Year, utcNowOffsetTest.Year);
Assert.AreEqual(utcNowOffset.Month, utcNowOffsetTest.Month);
Assert.AreEqual(utcNowOffset.Date, utcNowOffsetTest.Date);
Assert.AreEqual(utcNowOffset.Hour, utcNowOffsetTest.Hour);
Assert.AreEqual(utcNowOffset.Minute, utcNowOffsetTest.Minute);
Assert.AreEqual(utcNowOffset.Second, utcNowOffsetTest.Second);
}
[Test]
public void UnixMilliseconds()
{
DateTime utcNow = DateTime.UtcNow;
DateTimeOffset utcNowOffset = new DateTimeOffset(utcNow);
long unixTimestampInMilliseconds = utcNowOffset.ToUnixTimeMilliseconds();
DateTimeOffset utcNowOffsetTest = UnixDateTime.FromUnixTimeMilliseconds(unixTimestampInMilliseconds);
Assert.AreEqual(utcNowOffset.Year, utcNowOffsetTest.Year);
Assert.AreEqual(utcNowOffset.Month, utcNowOffsetTest.Month);
Assert.AreEqual(utcNowOffset.Date, utcNowOffsetTest.Date);
Assert.AreEqual(utcNowOffset.Hour, utcNowOffsetTest.Hour);
Assert.AreEqual(utcNowOffset.Minute, utcNowOffsetTest.Minute);
Assert.AreEqual(utcNowOffset.Second, utcNowOffsetTest.Second);
Assert.AreEqual(utcNowOffset.Millisecond, utcNowOffsetTest.Millisecond);
}
}
Я не понимаю. В .NET 4.6 в BCL уже есть эти методы (см., Например, мой комментарий к вопросу выше или некоторые другие новые ответы (2015 г.). Итак, какой смысл писать их снова? Вы имели в виду, что ваш ответ был решение для версий прежний до 4.6?
Преобразование времени 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()
Это не дает вам местного времени, вы получаете UTC.
@BerenddeBoer Это разумное значение по умолчанию. После этого вы можете применить произвольное смещение по своему усмотрению.
@BerenddeBoer Это неправильно понимает, что такое время unix. Время Unix - секунды с полуночи 1 января 1970 г. по всемирному координированному времени. Неважно, где вы находитесь, количество секунд с той эпохи не меняется. Преобразование его в удобочитаемые дисплеи местного времени, как и должно быть, отделены от этого универсального представления.
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 (double datetime))
var dt = DateTime.Now;
var unixTime = ((DateTimeOffset)dt).ToUnixTimeSeconds();
// 1510396991
var dt = DateTimeOffset.FromUnixTimeSeconds(1510396991);
// [11.11.2017 10:43:11 +00: 00]
Из .net 4.6 вы можете сделать это:
var dateTime = DateTimeOffset.FromUnixTimeSeconds(unixDateTime).DateTime;
Написано простейшее расширение, которое у нас работает. Если кто его ищет ...
public static class DateTimeExtensions
{
public static DateTime FromUnixTimeStampToDateTime(this string unixTimeStamp)
{
return DateTimeOffset.FromUnixTimeSeconds(long.Parse(unixTimeStamp)).UtcDateTime;
}
}
System.DateTimeOffset.Now.ToUnixTimeSeconds()
Вы можете использовать DateTimeOffset.
Например. У меня есть объект DateTime
var dateTime1=DateTime.Now;
Если я хочу преобразовать его в метки времени Unix, я могу добиться следующего
var unixTimeSeconds= new DateTimeOffset(dateTime1).ToUnixTimeSeconds()
Если вы хотите преобразовать unix timeStamp в обычный DateTime, вы можете использовать этот фрагмент кода:
var dateTime2 = DateTimeOffset.FromUnixTimeSeconds(unixTimeSeconds).LocalDateTime;
или же
var dateTime2 = DateTimeOffset.FromUnixTimeSeconds(unixTimeSeconds).UtcDateTime;
Для получения дополнительной информации перейдите по этой ссылке:
DateTimeOffset.ToUnixTimeSeconds - метод,
DateTimeOffset.FromUnixTimeSeconds
если вы буквально хотите Now как время UNIX, вы можете использовать DateTimeOffset.UtcNow.ToUnixTimeSeconds()
Предстоящий .NET 4.6 (который будет выпущен позже в этом году) представляет поддержку для этого. См. Методы
DateTimeOffset.FromUnixTimeSecondsиDateTimeOffset.ToUnixTimeSeconds. Существуют также методы для миллисекундного unix-времени.