我写了两个扩展方法来将时间从本地时间转换为UTC并返回。这就是我所拥有的:
public static DateTime ConvertUserTimeToUTCTime(this DateTime TheUserTime, string TheTimezoneID)
{
TheUserTime = new DateTime(TheUserTime.Year, TheUserTime.Month,
TheUserTime.Day, TheUserTime.Hour, TheUserTime.Minute,
TheUserTime.Second, DateTimeKind.Local);
TimeZoneInfo TheTZ = TimeZoneInfo.FindSystemTimeZoneById(TheTimezoneID);
TimeSpan TheOffset = TheTZ.GetUtcOffset(TheUserTime);
DateTimeOffset TheUTCTimeOffset = new DateTimeOffset(
TheUserTime, TheOffset).ToUniversalTime();
DateTime TheUTCTime = new DateTime(TheUTCTimeOffset.Year,
TheUTCTimeOffset.Month, TheUTCTimeOffset.Day, TheUTCTimeOffset.Hour,
TheUTCTimeOffset.Minute, 0, DateTimeKind.Utc);
return TheUTCTime;
}
public static DateTime ConvertUTCTimeToUserTime(this DateTime TheUTCTime,
string TheTimezoneID)
{
TimeZoneInfo TheTZ = TimeZoneInfo.FindSystemTimeZoneById(TheTimezoneID);
DateTime UTCTime = new DateTime(TheUTCTime.Year, TheUTCTime.Month,
TheUTCTime.Day, TheUTCTime.Hour, TheUTCTime.Minute, 0, DateTimeKind.Utc);
DateTime TheUserTime = TimeZoneInfo.ConvertTime(UTCTime, TheTZ);
return TheUserTime;
}
我经常在我的应用程序中使用这两个,我想知道它们是否是线程安全的。另外,把这两个方法放在一个抽象类中,然后让所有涉及时间运算的类从这个抽象类继承,会有什么好处吗?
感谢您对此时间转换主题的建议。
是的,它们是线程安全的。它们在变量命名方面很难看(为什么在所有内容之前都是"The",为什么是Pascal大小写?),您应该考虑使用DateTime.SpecifyKind
,但它们对共享状态没有任何作用。。。除非TimeZoneInfo
存在线程安全问题,否则它应该没事。(TimeZoneInfo
实际上指定实例成员不能保证是线程安全的,但也注意到它是不可变的。我希望它是线程安全。)
你绝对不应该把它们作为基类放在抽象类中——这将是对继承的滥用。它并不是真的代表了你想要专门化的抽象概念,是吗?这里的扩展方法是合理的。
您还应该非常仔细地思考,在转换不明确或无效的情况下,您希望第一个方法中的代码如何表现:例如,如果时钟从凌晨1点向前拨到凌晨2点,那么在当天的时区,凌晨1点30分是无效的。同样,如果它从凌晨2点回到凌晨1点,那么凌晨1点30分会出现两次。检查文档中的TimeZoneInfo.GetUtcOffset
,以确保在这些情况下从中返回的值是您想要的。
最后,考虑使用Noda Time,这是我的另一个.NET日期/时间API,它(我相信)让事情变得更干净,并使您对日期/时间转换等事情的选择非常明确。
(前几天我写了一篇关于这个主题的博客文章,就我一直在考虑的API的选择而言。欢迎反馈。)
我想确保我们谈论的是同一术语。线程安全是
如果一段代码只以保证多个线程同时安全执行的方式操作共享数据结构,那么它就是线程安全的。有各种策略可以使线程安全的数据结构
查看您的方法,它不会是线程安全的唯一方法是如果您正在更改类的成员或传入的参数
由于这些方法是静态的,所以您不能更改某个类的成员,因为它是线程安全的。
如果您正在更改进入方法的对象,则可能会违反下一个线程的安全性。
由于在您的代码中,您没有更改变量,因此您可以按照该路线进行操作。你也可以通过你使用的类型来判断。由于字符串是不可变的,所以它们总是线程安全的。由于DateTime是一个线程安全的结构。