Avatar ·

Как получить Unix timestamp (метку времени Unix) в C#

Всем привет! Я начинающий C# разработчик, и у меня возникла проблема при работе с датами и временем. Мне нужно получить Unix timestamp — количество секунд, прошедших с 1 января 1970 года (эпоха Unix). Это нужно для интеграции с внешним API, который принимает время в этом формате. Я пытался сделать что-то вроде: ```csharp DateTime now = DateTime.Now; long timestamp = (long)now; // Ошибка: неявное преобразование невозможно ``` Но компилятор выдает ошибку, что нельзя преобразовать DateTime в long. Потом я попробовал использовать свойство Ticks: ```csharp long timestamp = DateTime.Now.Ticks; ``` Но значение получается огромным (например, 638700000000000000), и это явно не Unix timestamp. Я понимаю, что Ticks считает от 1 января 0001 года, а не от 1970. Подскажите, как правильно получить Unix timestamp в C#? Желательно с примерами кода. Мне нужно как для текущего момента, так и для произвольной даты. Заранее спасибо! <<>>

Получение Unix timestamp в C#

Проблема, с которой вы столкнулись, типична для начинающих разработчиков. Unix timestamp (или Unix time) — это количество секунд (в некоторых случаях миллисекунд), прошедших с 1 января 1970 года 00:00:00 UTC. В C# нет встроенного свойства, которое бы напрямую возвращало это значение, но его легко вычислить.

Основной способ: использование DateTimeOffset

Самый правильный и современный подход — использовать структуру DateTimeOffset. Она учитывает часовой пояс и позволяет избежать ошибок, связанных с локальным временем.

// Текущий Unix timestamp (секунды)
long unixTimestamp = DateTimeOffset.UtcNow.ToUnixTimeSeconds();
Console.WriteLine(unixTimestamp); // Пример: 1698765432

// Unix timestamp в миллисекундах
long unixTimestampMs = DateTimeOffset.UtcNow.ToUnixTimeMilliseconds();
Console.WriteLine(unixTimestampMs); // Пример: 1698765432123

Если у вас есть произвольная дата, преобразуйте её в DateTimeOffset:

DateTime specificDate = new DateTime(2023, 10, 15, 12, 0, 0, DateTimeKind.Utc);
long timestamp = new DateTimeOffset(specificDate).ToUnixTimeSeconds();
Console.WriteLine(timestamp); // 1697371200

Обратное преобразование: из Unix timestamp в DateTime

Если вам нужно получить дату из Unix timestamp, используйте:

long timestamp = 1698765432;
DateTimeOffset dateTimeOffset = DateTimeOffset.FromUnixTimeSeconds(timestamp);
DateTime utcDateTime = dateTimeOffset.UtcDateTime;
Console.WriteLine(utcDateTime); // 2023-10-31 12:37:12

// Или сразу в локальное время
DateTime localDateTime = dateTimeOffset.LocalDateTime;
Console.WriteLine(localDateTime); // С учетом вашего часового пояса

Альтернативный способ (для старых версий .NET)

Если вы используете .NET Framework 4.6.1 или ниже (где нет методов ToUnixTimeSeconds), можно вычислить вручную:

DateTime epoch = new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc);
long timestamp = (long)(DateTime.UtcNow - epoch).TotalSeconds;
Console.WriteLine(timestamp);

Но настоятельно рекомендую перейти на .NET Core/.NET 5+ или хотя бы использовать DateTimeOffset — это проще и надёжнее.

Важные моменты

  • Всегда используйте UTC. Unix timestamp не зависит от часового пояса, поэтому берите DateTime.UtcNow или DateTimeOffset.UtcNow. Если возьмёте DateTime.Now, получите некорректное значение.
  • Проверяйте точность. Некоторые API требуют секунды, другие — миллисекунды. Убедитесь, что используете правильный метод (ToUnixTimeSeconds или ToUnixTimeMilliseconds).
  • Для .NET Framework 4.6+ методы ToUnixTimeSeconds и FromUnixTimeSeconds доступны в DateTimeOffset начиная с .NET Framework 4.6.

Надеюсь, это поможет! Если остались вопросы, спрашивайте.

<<>>

Использование TimeSpan для вычисления Unix timestamp

Если по каким-то причинам вы не можете использовать DateTimeOffset (например, очень старая версия .NET), можно воспользоваться TimeSpan и DateTime. Этот способ чуть более громоздкий, но тоже рабочий.

DateTime epoch = new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc);
DateTime utcNow = DateTime.UtcNow;
TimeSpan timeSinceEpoch = utcNow - epoch;

long unixTimestamp = (long)timeSinceEpoch.TotalSeconds;
Console.WriteLine(unixTimestamp);

Обратное преобразование:

long timestamp = 1698765432;
DateTime epoch = new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc);
DateTime date = epoch.AddSeconds(timestamp);
Console.WriteLine(date); // UTC время

Когда это может пригодиться

  • Вы пишете код для .NET Framework 4.5 или ниже.
  • Вам нужно больше контроля над вычислениями (например, для нестандартных эпох).
  • Вы хотите избежать дополнительных преобразований в DateTimeOffset.

Но помните: DateTimeOffset — это современный стандарт. Старайтесь использовать его везде, где это возможно.