Як можна перетворити 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.