简体   繁体   English

如何在特定时区转换日期时间?

[英]How to convert DateTime in Specific timezone?

I find it hard to understand how UTC works.我发现很难理解 UTC 是如何工作的。

I have to do the following but I'm still confused if I'd get the right result.我必须做以下操作,但是如果我得到正确的结果,我仍然感到困惑。

Objectives:目标:

  1. Ensure all saved dates in Database are in UTC format确保数据库中的所有保存日期均为UTC格式
  2. Update DefaultTimezone is in Manila time更新DefaultTimeZone在马尼拉时间
  3. Ensure all returned dates are in Manila Time确保所有返回的日期都在马尼拉时间

So the code is:所以代码是:

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

Sample usage:示例用法:

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

Now I get confused for 'TimeZone'.现在,我对“时区”感到困惑。 I don't know how to use it to get the objectives.我不知道如何使用它来获得目标。
Hope you understand my question and have the idea to get the objectives done.希望您理解我的问题并有想法完成目标。

Edit编辑

According to @raveturned answer, I get this following code:根据@raveturn的答案,我得到以下代码:

***Added in ConvertDate method ***添加了转换方法

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

**New Property **新属性

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

The .NET framework already has classes and methods available to convert DateTimes between different time zones. .NET框架已经具有可用于在不同时区之间转换DateTime的类和方法。 Have a look at the ConvertTime methods of the TimeZoneInfo class. 看一下TimeZoneInfo类的ConvertTime方法。

Edit: When you get the time to put into the database, assuming it was created with correct time zone information you can easily convert to UTC: 编辑:当您有时间放入数据库时​​,假设它是使用正确的时区信息创建的,则可以轻松转换为UTC:

DateTime utcTime = inputDateTime.ToUniversalTime();

Get timeInfo as done in the question edit: 获取问题编辑中的timeInfo:

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

When you send the database time to user, convert it to the correct timezone using timeInfo . 将数据库时间发送给用户时,请使用timeInfo将其转换为正确的时区。

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

Personally I'd try and keep this logic separate from the propery get/set methods. 我个人将尝试将此逻辑与适当的获取/设置方法分开。

TimeZoneInfo infotime = TimeZoneInfo.FindSystemTimeZoneById("Eastern Standard Time (Mexico)");
DateTime thisDate = TimeZoneInfo.ConvertTimeFromUtc(datetimeFromBD, infotime);
var date = System.TimeZoneInfo.ConvertTimeFromUtc(
    DateTime.UtcNow, 
    TimeZoneInfo.FindSystemTimeZoneById("Pacific Standard Time"));

To help others: 帮助他人:

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

For anyone facing problem in getting TimeZoneInfo in cross-platform (different time zone ids between Windows and Linux), .NET 6 addresses this issue:对于在跨平台获取 TimeZoneInfo 时遇到问题的任何人(Windows 和 Linux 之间的不同时区 id),.NET 6 解决了这个问题:

Starting with this release, the TimeZoneInfo.FindSystemTimeZoneById method will automatically convert its input to the opposite format if the requested time zone is not found on the system.从此版本开始,如果在系统上未找到请求的时区,TimeZoneInfo.FindSystemTimeZoneById 方法将自动将其输入转换为相反的格式。 That means that you can now use either IANA or Windows time zone IDs on any operating system that has time zone data installed*.这意味着您现在可以在任何安装了时区数据的操作系统上使用 IANA 或 Windows 时区 ID*。 It uses the same CLDR mappings, but gets them through .NET's ICU globalization support, so you don't have to use a separate library.它使用相同的 CLDR 映射,但通过 .NET 的 ICU 全球化支持获取它们,因此您不必使用单独的库。

A brief example:一个简单的例子:

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

Find more info here 在此处查找更多信息

And as mentioned in other answers: to get DateTime in the desired timezone from UTC, use TimeZoneInfo.ConvertTimeFromUtc(DateTime, TimeZoneInfo) Method正如其他答案中所述:要从 UTC 获取所需时区的DateTime ,请使用TimeZoneInfo.ConvertTimeFromUtc(DateTime, TimeZoneInfo) 方法

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM