Работа с датами и временем в 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();
Только полноправные пользователи могут оставлять комментарии. Аутентифицируйтесь пожалуйста, используя сервисы.