Як можна перетворити DateTime на кількість секунд з 1970 року?


119

Я намагаюся перетворити змінну C # DateTime в час Unix, тобто кількість секунд з 1 січня 1970 р. Схоже, що DateTime насправді реалізований як кількість "тиків" з 1 січня 0001 року.

Моя поточна думка полягає в тому, щоб відняти 1 січня 1970 року від мого DateTime, як це:

TimeSpan span= DateTime.Now.Subtract(new DateTime(1970,1,1,0,0,0));
return span.TotalSeconds;

Чи є кращий спосіб?


1
Можливий дублікат того, як ви конвертуєте епоху в C #?
— jpaugh

Відповіді:


195

Це в основному все. Це методи, які я використовую для перетворення в епоху часу Unix:

public static DateTime ConvertFromUnixTimestamp(double timestamp)
{
    DateTime origin = new DateTime(1970, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc);
    return origin.AddSeconds(timestamp);
}

public static double ConvertToUnixTimestamp(DateTime date)
{
    DateTime origin = new DateTime(1970, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc);
    TimeSpan diff = date.ToUniversalTime() - origin;
    return Math.Floor(diff.TotalSeconds);
}

Оновлення: Станом на .Net Core 2.1 та .Net Standard 2.1 a DateTime, рівний Unix Epoch, може бути отриманий зі статики DateTime.UnixEpoch.


1
Варто зазначити, що якщо ви хочете перетворити на мілісекунди для більш точних часових позначок або сумісності об'єкта Javascript Date (), вам потрібно використовувати довгий замість int для типу часової мітки.
— Радянський

3
Не працювали для мене. Ця відповідь зробив трюк: stackoverflow.com/questions/249760 / ...
— Zeezer

@Jonny - ToUniversalTime () перетворюється на UTC, тому він враховує UTC.
— Дейв Сверський

4
DateTime походження = новий DateTime (1970, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc); Цікаво, що ніхто цього не запропонував. Дуже часто у вас будуть мілісекунди, що представляють час Utc. І якщо у вас не t specify this explicitly and somewhere later in code youбуде ToUniversalTime (), то ви закінчитеся з поганим часом Utc, оскільки за замовчуванням DateTime НЕ є Utc.
— крутий

52

Якщо для решти вашої системи все в порядку з DateTimeOffset замість DateTime, є дійсно зручна функція:

long unixSeconds = DateTimeOffset.Now.ToUnixTimeSeconds();

7
Це більш чистий спосіб, але він доступний лише в рамках 4.6 msdn.microsoft.com/en-us/library/…
— Оскар Fraxedas

1
Приємно. І звичайно, для переходу з unix на DateTimeOffset, ви можете використовувати var time = DateTimeOffset.FromUnixTimeSeconds(5000); MS Doc
— Йорданія

22

Єдине, що я бачу, це те, що це повинно бути з півночі 1 січня 1970 року за UTC

TimeSpan span= DateTime.Now.Subtract(new DateTime(1970,1,1,0,0,0, DateTimeKind.Utc));
return span.TotalSeconds;

7
Чи має бути DateTime.UtcNow?
— oferei

14

Ви, ймовірно, хочете використовувати DateTime.UtcNow, щоб уникнути проблеми часового поясу

TimeSpan span= DateTime.UtcNow.Subtract(new DateTime(1970,1,1,0,0,0)); 

Єдиний спосіб уникнути проблем із часовим поясом - 1) залишатися невідомими і підтримувати лише один часовий пояс, або 2) обробляти часові пояси (принаймні) скрізь, де ви взаємодієте з іншою системою або кінцевим користувачем. Зокрема, використання UTC всюди всередині є лише частиною битви. У першому сценарії додавання UTC-дати фактично ще більше погіршує проблему, поки ви не будете готові виконати всі (2), оскільки ви переходите від підтримки будь-якого одного часового поясу до підтримки лише UTC.
— jpaugh

1

Такий підхід буде корисним, якщо відповідна дата та час знаходиться в UTC, або представляє місцевий час у місцевості, яка ніколи не спостерігала літнього часу. Програми різниці DateTime не враховують літній час, і, отже, вважати півночі 1 червня як кратну 24 години після півночі 1 січня. Я не знаю нічого про це в Windows, що повідомляє про історичні правила літнього часу для поточних locale, тому я не думаю, що існує жодного хорошого способу правильно впоратися з будь-яким часом до останньої зміни літнього режиму.


0

Ви можете створити startTime і endTime DateTime, потім виконати endTime.Subtract (startTime). Потім виведіть свій проміжок. Секунди.

Я думаю, що це має працювати.


0

Я використовую 2000 рік замість епохи часу в своєму обчисленні. Робота з меншими числами легко зберігати та транспортувати, і це зручно для JSON.

2000 рік був другим 946684800 епохи.

2000 рік був другим 63082281600 з 1 січня 0001 року.

DateTime.UtcNow Ticks починається з 1-го січня 0001 року

Секунди з 2000 року :

DateTime.UtcNow.Ticks/10000000-63082281600

Секунди від часу Unix:

DateTime.UtcNow.Ticks/10000000-946684800

Наприклад, 2020 рік - це:

var year2020 = (новий DateTime ()). AddYears (2019) .Ticks; // Тому що DateTime починається вже з 1 року

637134336000000000 Кліщі з 1 січня 0001 року

63713433600 секунд з 1-го січня 0001 року

1577836800 секунд з епохового часу

631152000 секунд з 2000 року

Список літератури:

Конвертор часу епохи: https://www.epochconverter.com

Конвертор року 1: https://www.epochconverter.com/seconds-days-since-y0

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.