Работа с часовыми поясами DateTime


Я пишу некоторый код, где у меня есть DateTime в UTC, и мне нужно отобразить это как LocalTime, где у меня есть объект культуры для двух часовых поясов.

Вот мой код:

public void CultureDateTimeLocalTime()
{
    DateTime dateTimeUtcNow = DateTime.UtcNow;
    DateTime convertedDate = DateTime.SpecifyKind(dateTimeUtcNow, DateTimeKind.Utc);
    DateTime dateTimeLocalTime = convertedDate.ToLocalTime();

    String format = "MM/dd/yyyy hh:mm:sszzz";

    string localTime = dateTimeLocalTime.ToString(format);

    CultureInfo cultureNZ = new CultureInfo("en-NZ");
    CultureInfo cultureUS = new CultureInfo("en-US");

    DateTime DateTimeNZ;
    bool parseNZ = DateTime.TryParse(localTime, cultureNZ, DateTimeStyles.None, out DateTimeNZ);
    string outputNZ = DateTimeNZ.ToString("F");

    DateTime DateTimeUS;
    bool parseUS = DateTime.TryParse(localTime, cultureUS, DateTimeStyles.None, out DateTimeUS);
    string outputUS = DateTimeUS.ToString("F");
}

public void CultureDateTimeLocalTime2()
{
    DateTime dateTimeUtcNow = DateTime.UtcNow;
    DateTime convertedDate = DateTime.SpecifyKind(dateTimeUtcNow, DateTimeKind.Utc);
    DateTime dateTimeLocalTime = convertedDate.ToLocalTime();

    String format = "MM/dd/yyyy hh:mm:sszzz";

    string localTime = dateTimeLocalTime.ToString(format);

    CultureInfo cultureNZ = new CultureInfo("en-NZ");
    CultureInfo cultureUS = new CultureInfo("en-US");

    DateTime DateTimeNZ = DateTime.ParseExact(localTime, format, cultureNZ.DateTimeFormat);
    string outputNZ = DateTimeNZ.ToString("F");

    DateTime DateTimeUS = DateTime.ParseExact(localTime, format, cultureUS.DateTimeFormat);
    string outputUS = DateTimeUS.ToString("F");
}

В обеих функциях outputNZ и outputUS одинаковы. Почему это так?

Заранее благодарю.

2 2

2 ответа:

CultureInfo содержит правила форматирования даты, времени и чисел для определенного языка и региональных параметров. Нет никаких правил о часовом поясе этой культуры, потому что для большинства культур и часовых поясов нет однозначного соответствия, поэтому вы не можете использовать CultureInfo, чтобы волшебным образом учитывать часовые пояса, когда дата форматируется в виде строки.

Что вам нужно, так это Новая Зеландия.TimeZoneInfo:

var nzTimeZoneInfo = TimeZoneInfo.FindSystemTimeZoneById("New Zealand Standard Time");
var utcNow = DateTime.UtcNow;
var nzNow = TimeZoneInfo.ConvertTimeFromUtc(utcNow, nzTimeZoneInfo);
var outputNz = nzNow.ToString("F", CultureInfo.GetCultureInfo("en-NZ"));
Вы можете использовать ту же логику для преобразования в часовой пояс США, но здесь становится очевидным, что вы не можете вывести часовой пояс из CultureInfo, потому что в США есть много часовых поясов, и вы должны решить, какой из них использовать.

Кроме того, при работе с датой и временем вы должны конвертировать только в строковый формат на последнем шаге. Ваш код работает, потому что вы тщательно контролируете формат, который вы используете для кругового перехода к строке, но этот круговой переход необязателен, и я исправил много ошибок, когда этот код кругового перехода имел неявное предположение о региональных настройках компьютера, который был выбран. не всегда верно, когда код выполняется в другой среде.

отказ от ответственности: я проверил это только со вторым методом.

Оба метода разбирают на DateTime , но вы выводите с тем же ToString, Вы можете отформатировать эту строку с помощью DateTimeFormatInfo.LongDatePattern

string outputNZ = DateTimeNZ.ToString(cultureNZ.DateTimeFormat.LongDatePattern);
string outputUS = DateTimeUS.ToString(cultureUS.DateTimeFormat.LongDatePattern);
// or string outputUS = DateTimeUS.ToString(cultureUS.DateTimeFormat);

Пример IDEOne

Из документации для DateTime.ToString

Этот метод использует информацию форматирования, полученную из текущей культуры

Поскольку ваша культура никогда не меняется, выходные данные также не меняются