我有一个日志文件,其中包含格式如下的日期/时间字符串:
2019/10/01 15:30
如您所见,字符串不包含任何时区信息。但是,我确实知道时间在其中所代表的时区。
如果我在我自己的PC上使用这个C#代码,它的本地时区设置是正确的,那么时间将按预期进行解析。我希望将本地时间转换为UTC,以便插入数据库。
Time.ParseExact("2019/10/01 15:30", "yyyy/MM/dd HH:mm", provider, DateTimeStyles.AdjustToUniversal & DateTimeStyles.AssumeLocal);
但是,如果我在我的Docker主机上运行此代码,它的时区设置为UTC,则时间被解析为UTC。这是有意义的,因为在使用UTC的Docker主机上,
AssumeLocal
将与UTC相同。
仅仅应用人工偏移是不够的,因为夏令时。此外,其中一些日志是历史的,可以追溯到DST更改之前,因此即使使用算法也会很复杂,而且似乎应该解决一些问题(例如,给定日期和时区,确定它是否在DST中,然后相应地调整到UTC )。
我想要做的是显式地指定时间戳的时区,并让框架同时使用给定的时区和实际的日期来正确地将时间转换为UTC。我看过 这个问题 和 这个问题 ,但它们似乎都依赖于系统本身被设置为您想要假定日期在的时区。
第二个问题似乎已经开始解决假定一个已知时区的问题,但是响应只是在解析的时间上使用
GetUtcOffset
来确定抵消时间的时间量。这假定时间已经在所需的时区中被解析。
发布于 2019-10-03 20:53:54
我相信你要找的是 TimeZoneInfo 。
使用TimeZoneInfo,您可以从 TimeZoneInfo.FindSystemTimeZoneById 获得所需的信息。
这些Ids是基于操作系统的,但是只要您的所有容器都在Linux上(举个例子),您就可以使用它获得UTC的存储时间。您提到您知道您的字符串位于哪个时区,因此您可能需要一些东西来将其转换为TimeZoneInfo可读的Ids。
从 TimeZoneInfo.FindSystemTimeZoneById 获取的代码示例
using System;
public class Example
public static void Main()
// Get time in local time zone
DateTime thisTime = DateTime.Now;
Console.WriteLine("Time in {0} zone: {1}", TimeZoneInfo.Local.IsDaylightSavingTime(thisTime) ?
TimeZoneInfo.Local.DaylightName : TimeZoneInfo.Local.StandardName, thisTime);
Console.WriteLine(" UTC Time: {0}", TimeZoneInfo.ConvertTimeToUtc(thisTime, TimeZoneInfo.Local));
// Get Tokyo Standard Time zone
TimeZoneInfo tst = TimeZoneInfo.FindSystemTimeZoneById("Tokyo Standard Time");
DateTime tstTime = TimeZoneInfo.ConvertTime(thisTime, TimeZoneInfo.Local, tst);
Console.WriteLine("Time in {0} zone: {1}", tst.IsDaylightSavingTime(tstTime) ?
tst.DaylightName : tst.StandardName, tstTime);
Console.WriteLine(" UTC Time: {0}", TimeZoneInfo.ConvertTimeToUtc(tstTime, tst));