使用DateTime时区

时间:2015-03-12 07:43:53

标签: c# datetime timezone utc localtime

我正在编写一些代码,其中我有一个UTC的DateTime,我需要将其显示为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都是相同的。这是为什么?

提前致谢。

2 个答案:

答案 0 :(得分:5)

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推断出时区,因为美国有许多时区,您必须决定使用哪个时区

此外,在处理日期和时间时,您应该只在最后一步中转换为字符串格式。您的代码恰好工作,因为您仔细控制了用于往返字符串的格式,但这次往返是不必要的,我修复了许多错误,这些往返代码隐含了关于区域设置的错误。当代码在另一个环境中执行时,计算机并不总是如此。

答案 1 :(得分:0)

免责声明:我只用第二种方法对此进行了测试。

这两种方法都解析为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

的文档
  

此方法使用从当前文化

派生的格式信息

由于您的文化永远不会改变,因此输出不会