【问题标题】:How to convert DateTime in Specific timezone?如何在特定时区转换 DateTime?
【发布时间】:2018-11-24 09:40:22
【问题描述】:

我很难理解 UTC 的工作原理。

我必须执行以下操作,但如果我能得到正确的结果,我仍然感到困惑。

目标:

  1. 确保数据库中所有保存的日期均为 UTC 格式
  2. 更新 DefaultTimezone 为马尼拉时间
  3. 确保所有返回的日期都在马尼拉时间

所以代码是:

public ConvertDate(DateTime? dateTime)
{
    if (dateTime != null)
    {
        Value = (DateTime)dateTime;
        TimeZone = GetFromConfig.DefaultTimeZone(); 
    }
}


public ConvertDate(DateTime? dateTime, int GMTTimeZone)
{
    if (dateTime != null)
    {
        Value = (DateTime)dateTime;
        TimeZone = GMTTimeZone;
    }
}


public int TimeZone
{
    get { return m_TimeZone; }
    set { m_TimeZone = value; }
}


DateTime m_Value;
public DateTime Value
{
    get { return m_Value; }
    set 
    { 
        m_Value = value;
        DateTime converted = m_Value.ToUniversalTime().ToLocalTime();
    }
}

示例用法:

DateTime SampleInputFromUser = new DateTime(2012, 1, 22);
ConvertDate newConversion = new ConvertDate(SampleInputFromUser, 21);
DateTime answer = newConversion.Value;

现在我对“时区”感到困惑。我不知道如何使用它来获得目标。
希望您理解我的问题并有想法完成目标。

编辑

根据@raveturned 的回答,我得到以下代码:

***在 ConvertDate 方法中添加

TimeZoneInfo timeInfo = TimeZoneInfo.FindSystemTimeZoneById(GetFromConfig.ManilaTimeZoneKey());
ManilaTime = TimeZoneInfo.ConvertTime(dateTime.Value, TimeZoneInfo.Local, timeInfo).ToUniversalTime();

**新属性

DateTime _ManilaTime;
public DateTime ManilaTime
{
    get { return _ManilaTime; }
    set { _ManilaTime = value; }
}

【问题讨论】:

标签: c# datetime utc


【解决方案1】:

.NET 框架已经具有可用于在不同时区之间转换 DateTime 的类和方法。看看 TimeZoneInfo 类的 ConvertTime 方法。

编辑:当您有时间放入数据库时​​,假设它是使用正确的时区信息创建的,您可以轻松转换为 UTC:

DateTime utcTime = inputDateTime.ToUniversalTime();

在问题编辑中获取 timeInfo:

TimeZoneInfo timeInfo = TimeZoneInfo.FindSystemTimeZoneById(GetFromConfig.ManilaTimeZoneKey());

当您将数据库时间发送给用户时,使用timeInfo 将其转换为正确的时区。

DateTime userTime = TimeZoneInfo.ConvertTimeFromUtc(dbDateTime, timeInfo);

我个人会尝试将此逻辑与属性 get/set 方法分开。

【讨论】:

【解决方案2】:
var date = System.TimeZoneInfo.ConvertTimeFromUtc(
    DateTime.UtcNow, 
    TimeZoneInfo.FindSystemTimeZoneById("Pacific Standard Time"));

【讨论】:

  • 虽然这段代码可以回答作者的问题,但它缺乏解释。原始的 sn-ps 没有帮助。查看帮助页面了解更多关于how to write a good answer的信息。
【解决方案3】:
TimeZoneInfo infotime = TimeZoneInfo.FindSystemTimeZoneById("Eastern Standard Time (Mexico)");
DateTime thisDate = TimeZoneInfo.ConvertTimeFromUtc(datetimeFromBD, infotime);

【讨论】:

    【解决方案4】:

    帮助他人:

        static void ChangeTimezone()
        {
            // Timezone string here:
            foreach (TimeZoneInfo z in TimeZoneInfo.GetSystemTimeZones())
                Console.WriteLine(z.Id);
    
            // Use one of those timezone strings
            DateTime localDt = DateTime.Today;
            DateTime utcTime = localDt.ToUniversalTime();
            TimeZoneInfo timeInfo = TimeZoneInfo.FindSystemTimeZoneById("US Eastern Standard Time");
            DateTime estDt = TimeZoneInfo.ConvertTimeFromUtc(utcTime, timeInfo);
            return;
        }
    

    【讨论】:

      【解决方案5】:

      对于在跨平台获取 TimeZoneInfo(Windows 和 Linux 之间的时区 ID 不同)时遇到问题的任何人,.NET 6 解决了这个问题:

      从此版本开始,如果在系统上找不到请求的时区,TimeZoneInfo.FindSystemTimeZoneById 方法将自动将其输入转换为相反的格式。这意味着您现在可以在任何安装了时区数据的操作系统上使用 IANA 或 Windows 时区 ID*。它使用相同的 CLDR 映射,但通过 .NET 的 ICU 全球化支持获取它们,因此您不必使用单独的库。

      一个简单的例子:

      // Both of these will now work on any supported OS where ICU and time zone data are available.
      TimeZoneInfo tzi1 = TimeZoneInfo.FindSystemTimeZoneById("AUS Eastern Standard Time");
      TimeZoneInfo tzi2 = TimeZoneInfo.FindSystemTimeZoneById("Australia/Sydney");
      

      了解更多信息here

      正如其他答案中所述:要从 UTC 获取所需时区的 DateTime,请使用 TimeZoneInfo.ConvertTimeFromUtc(DateTime, TimeZoneInfo) Method

      【讨论】:

        猜你喜欢
        • 2017-11-23
        • 1970-01-01
        • 1970-01-01
        • 2016-06-29
        • 1970-01-01
        • 2019-05-12
        • 2013-08-06
        • 2015-09-05
        相关资源
        最近更新 更多