Работа с датами и временем в netcore
Когда вы преобразуете DateTimeOffset в Unix-время (timestamp) в .NET Core, вы всегда получаете значение в UTC. Это связано с тем, что Unix-время — это количество секунд (или миллисекунд), прошедших с 1 января 1970 года 00:00:00 UTC.
Пример на C#
using System;
class Program
{
   static void Main()
   {
       // Создаём DateTimeOffset с локальным временем (например, Москва, UTC+3)
       DateTimeOffset localTime = new DateTimeOffset(
           new DateTime(2025, 9, 1, 12, 0, 0), // 1 сентября 2025, 12:00
           TimeSpan.FromHours(3) // UTC+3
       );
       // Преобразуем в Unix-время (секунды с 1970-01-01 UTC)
       long unixTime = localTime.ToUnixTimeSeconds();
       // Выводим результат
       Console.WriteLine($"Локальное время: {localTime}");
       Console.WriteLine($"Unix-время (UTC): {unixTime}");
       // Для проверки: преобразуем обратно
       DateTimeOffset fromUnix = DateTimeOffset.FromUnixTimeSeconds(unixTime);
       Console.WriteLine($"Обратно в DateTimeOffset: {fromUnix}");
   }
}
Объяснение
- DateTimeOffsetхранит дату, время и смещение от UTC (например,- +03:00для Москвы).
- Метод ToUnixTimeSeconds()автоматически преобразует локальное время в UTC, используя смещение, и только затем считает количество секунд с 1970 года.
- Если вы снова преобразуете Unix-время в DateTimeOffset(методомFromUnixTimeSeconds), вы получите время в UTC.
Важно
- Если вам нужно работать с локальным временем, используйте DateTimeOffsetи учитывайте смещение.
- Unix-время всегда не зависит от часового пояса и основано на UTC.
Когда вы работаете с DateTime (не DateTimeOffset) в .NET, у вас есть два ключевых момента, которые определяют, как преобразовать его в Unix-время (UTC):
1. DateTime.Kind — тип времени
У DateTime есть свойство Kind, которое может принимать три значения:
- DateTimeKind.Unspecified— не указано, UTC это или локальное время (по умолчанию).
- DateTimeKind.Utc— время в UTC.
- DateTimeKind.Local— локальное время (с учётом часового пояса).
2. Как преобразовать в Unix-время (UTC)
a) Если DateTime уже в UTC (Kind == Utc):
DateTime utcTime = DateTime.UtcNow; // или любое другое UTC-время
long unixTime = new DateTimeOffset(utcTime).ToUnixTimeSeconds();Здесь смещение не нужно — время уже в UTC.
b) Если DateTime — локальное время (Kind == Local):
DateTime localTime = DateTime.Now; // локальное время
DateTimeOffset localTimeOffset = new DateTimeOffset(localTime);
long unixTime = localTimeOffset.ToUnixTimeSeconds();Метод ToUnixTimeSeconds() автоматически учтёт смещение локального времени относительно UTC.
c) Если DateTime — неопределённого типа (Kind == Unspecified):
В этом случае вы должны явно указать, считать ли это время UTC или локальным. Например:
DateTime unspecifiedTime = new DateTime(2025, 9, 1, 12, 0, 0); // Kind = Unspecified
// Вариант 1: считаем, что это UTC
DateTimeOffset utcTimeOffset = new DateTimeOffset(unspecifiedTime, TimeSpan.Zero);
long unixTime = utcTimeOffset.ToUnixTimeSeconds();
// Вариант 2: считаем, что это локальное время (например, UTC+3)
DateTimeOffset localTimeOffset = new DateTimeOffset(unspecifiedTime, TimeSpan.FromHours(3));
long unixTimeLocal = localTimeOffset.ToUnixTimeSeconds();Пример с объяснением
using System;
class Program
{
   static void Main()
   {
       // Локальное время (например, Москва, UTC+3)
       DateTime localTime = DateTime.Now;
       Console.WriteLine($"Локальное время: {localTime}, Kind: {localTime.Kind}");
       // Преобразуем в Unix-время (автоматически учтёт смещение)
       DateTimeOffset localTimeOffset = new DateTimeOffset(localTime);
       long unixTime = localTimeOffset.ToUnixTimeSeconds();
       Console.WriteLine($"Unix-время (UTC): {unixTime}");
       // Обратно в DateTimeOffset (будет в UTC)
       DateTimeOffset fromUnix = DateTimeOffset.FromUnixTimeSeconds(unixTime);
       Console.WriteLine($"Обратно в DateTimeOffset (UTC): {fromUnix}");
   }
}Выводы
- DateTimeбез- Kindили с- Kind = Unspecifiedтребует явного указания смещения.
- DateTime.Kind = Utcили- DateTime.Kind = Localпозволяют автоматически корректно преобразовать в Unix-время.
- Unix-время всегда основано на UTC.
Если нужно работать с конкретным часовым поясом (например, не локальным, а другим), используйте TimeZoneInfo для преобразования.
Вот пример, как работать с конкретным часовым поясом (например, не локальным, а, скажем, Нью-Йорком или Токио) при преобразовании DateTime в Unix-время (UTC).
Пример: Преобразование DateTime в Unix-время с учётом произвольного часового пояса
using System;
class Program
{
   static void Main()
   {
       // 1. Создаём DateTime (без указания Kind)
       DateTime unspecifiedTime = new DateTime(2025, 9, 1, 12, 0, 0);
       Console.WriteLine($"Исходное время: {unspecifiedTime}, Kind: {unspecifiedTime.Kind}");
       // 2. Указываем часовой пояс (например, Нью-Йорк, UTC-4)
       TimeZoneInfo nyTimeZone = TimeZoneInfo.FindSystemTimeZoneById("Eastern Standard Time");
       DateTime nyTime = TimeZoneInfo.ConvertTimeFromUtc(unspecifiedTime, nyTimeZone);
       Console.WriteLine($"Время в Нью-Йорке: {nyTime}, Kind: {nyTime.Kind}");
       // 3. Преобразуем в DateTimeOffset с правильным смещением
       DateTimeOffset nyTimeOffset = new DateTimeOffset(nyTime, nyTimeZone.GetUtcOffset(nyTime));
       Console.WriteLine($"DateTimeOffset для Нью-Йорка: {nyTimeOffset}");
       // 4. Получаем Unix-время (UTC)
       long unixTime = nyTimeOffset.ToUnixTimeSeconds();
       Console.WriteLine($"Unix-время (UTC): {unixTime}");
       // 5. Проверяем: преобразуем обратно
       DateTimeOffset fromUnix = DateTimeOffset.FromUnixTimeSeconds(unixTime);
       Console.WriteLine($"Обратно в DateTimeOffset (UTC): {fromUnix}");
   }
}Объяснение шагов:
DateTime без Kind Создаём DateTime с неопределённым типом (Unspecified). Это может быть любое время, но без привязки к часовому поясу.
Преобразование в нужный часовой пояс Используем TimeZoneInfo.FindSystemTimeZoneById для получения информации о часовом поясе (например, Нью-Йорк — "Eastern Standard Time"). Метод TimeZoneInfo.ConvertTimeFromUtc преобразует время из UTC в указанный часовой пояс.
Создание DateTimeOffset Преобразуем DateTime в DateTimeOffset, явно указывая смещение для данного времени в выбранном часовом поясе.
Получение Unix-времени Метод ToUnixTimeSeconds() автоматически преобразует время в UTC и возвращает количество секунд с 1970 года.
Обратная проверка Преобразуем Unix-время обратно в DateTimeOffset, чтобы убедиться, что всё корректно.
Важные моменты:
- Идентификаторы часовых поясов зависят от ОС. Для Windows используйте имена из реестра Windows, для Linux — из базы данных IANA.
- Если вы работаете с локальным временем, используйте TimeZoneInfo.Localвместо конкретного пояса.
- Если DateTimeуже в UTC, просто создайтеDateTimeOffsetс нулевым смещением.
Пример для Токио (UTC+9)
TimeZoneInfo tokyoTimeZone = TimeZoneInfo.FindSystemTimeZoneById("Tokyo Standard Time");
DateTime tokyoTime = TimeZoneInfo.ConvertTimeFromUtc(unspecifiedTime, tokyoTimeZone);
DateTimeOffset tokyoTimeOffset = new DateTimeOffset(tokyoTime, tokyoTimeZone.GetUtcOffset(tokyoTime));
long unixTimeTokyo = tokyoTimeOffset.ToUnixTimeSeconds(); 
                                
Только полноправные пользователи могут оставлять комментарии. Аутентифицируйтесь пожалуйста, используя сервисы.