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