使用 DateTime 时区

Working with DateTime Time Zones

我正在编写一些代码,其中有一个 UTC 日期时间,我需要将其显示为 LocalTime,其中我有两个时区的 Culture 对象。

这是我的代码:

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");
}

在这两个函数中,outputNZoutputUS 是相同的。这是为什么?

提前致谢。

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 Example

来自 DateTime.ToString

的文档

This method uses formatting information derived from the current culture

由于您的文化从未改变,因此输出也不会改变