代码之家  ›  专栏  ›  技术社区  ›  Simon

使用DateTime时区

  •  2
  • Simon  · 技术社区  · 9 年前

    我正在编写一些代码,其中我有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");
    }
    

    在这两种功能中 outputNZ outputUS 都是一样的。这是为什么?

    提前感谢。

    2 回复  |  直到 9 年前
        1
  •  5
  •   Martin Liversage    9 年前

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

    您可以使用相同的逻辑转换为美国时区,但这里很明显,您无法从 文化信息 因为美国有很多时区,你必须决定使用哪个时区。

    此外,在处理日期和时间时,只应在最后一步中转换为字符串格式。您的代码之所以能正常工作,是因为您仔细控制了往返字符串所使用的格式,但这种往返是不必要的,我已经修复了许多错误,因为这种往返代码对计算机的区域设置有隐含的假设,而当代码在另一个环境中执行时,这种假设并不总是正确的。

        2
  •  1
  •   Sayse    9 年前

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

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

    此方法使用从当前区域性派生的格式信息

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