如何在特定时区转换 DateTime?
Posted
技术标签:
【中文标题】如何在特定时区转换 DateTime?【英文标题】:How to convert DateTime in Specific timezone? 【发布时间】:2018-11-24 09:40:22 【问题描述】:我很难理解 UTC 的工作原理。
我必须执行以下操作,但如果我能得到正确的结果,我仍然感到困惑。
目标:
-
确保数据库中所有保存的日期均为 UTC 格式
更新 DefaultTimezone 为马尼拉时间
确保所有返回的日期都在马尼拉时间
所以代码是:
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;
【问题讨论】:
***.com/questions/246498/…的可能重复 【参考方案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 方法分开。
【讨论】:
这个list of timezone IDs 可能会有所帮助【参考方案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
【讨论】:
以上是关于如何在特定时区转换 DateTime?的主要内容,如果未能解决你的问题,请参考以下文章
如何在特定时区(最好是我的应用程序的默认时区,而不是 UTC)中创建新的 DateTime 对象?