我创建结构名称DateTimeZone,我将其设置为采用UTC时间,然后我将其设置为当地时间。
DateTimeZone time = DateTime.Now;//time will equal the UTC time
DateTime localTime= time; // local time will equal the Local time
结构
public struct DateTimeZone
{
private DateTime dateTime;
// public DateTimeZone Value { get; }
public static implicit operator DateTimeZone(DateTime value)
{
return new DateTimeZone() { dateTime = value.ToUniversalTime() };
}
public static implicit operator DateTime(DateTimeZone value)
{
return value.dateTime.ToLocalTime();
}
}
我的问题:是否有最简单的方法来实现这个而不是结构? 当我保存在DB中导致实体框架工作时,这个结构有异常, 所以我每次使用struct时都需要进行映射,如何以简洁的方式进行映射?
答案 0 :(得分:1)
也许你应该尝试这个:
public struct DateTimeZone
{
public DateTime DateTime;
public static explicit operator DateTimeZone(DateTime dt)
{
return new DateTimeZone { DateTime = dt.ToUniversalTime() };
}
}
var time = (DateTimeZone)DateTime.Now;
var localTime = time.DateTime;
答案 1 :(得分:1)
一些事情:
小心命名。名称为DateTimeZone
的对象应仅包含1)时区信息,或2)日期和时间和时区。你的对象只是DateTime
周围的封装包装器,因此它们都不属于这些。
隐式操作可能是邪恶的 - 特别是如果它们改变了您正在使用的值的含义。我不建议将它们与日期/时间一起使用,除非你真的知道你正在做什么。对于这个对象的任何用户来说,很快就会对你实际使用的价值感到困惑。
ToUniversalTime
和ToLocalTime
函数会根据分配给DateTimeKind
对象的.Kind
属性的DateTime
更改其行为与...合作。您似乎正在创建一个API,其中DateTime
始终是本地的,DateTimeZone
始终是UTC,但DateTimeKind
会妨碍这个想法。
正如评论中所提到的,您可能会考虑使用Noda Time,这是一个非常可靠且经过深思熟虑的API。在Noda Time中,Instant
类型始终表示UTC,LocalDateTime
类型始终表示无时区的日期和时间。时区由DateTimeZone
表示(请参阅与您的姓名冲突),ZonedDateTime
类型将这些结合起来,这样您就可以获得即时信息,本地时间信息以及相关联的信息。时区。
您提到了实体框架。不幸的是,EF无法直接使用您的自定义对象或使用Noda Time。它无法进行简单的类型转换。这已被要求,但尚未实施。 You can follow the work item for it here。您可以使用的解决方法是“伙伴属性”,as described here。他们不好玩,但他们工作。居多。
您可能会觉得使用DateTime
是合理的,并在需要时手动调用ToUniversalTime
或ToLocalTime
等方法。如果您希望EF从数据库加载时正确设置DateTimeKind
,请参阅this answer。
请注意,ToUniversalTime
和ToLocalTime
都可以使用代码恰好运行的计算机的本地时区。这适用于桌面和移动应用程序,但很少需要Web应用程序,因为更改服务器的时区可能会极大地影响数据。请考虑通过内置的TimeZoneInfo
类或Noda Time中的DateTimeZone
类来处理指定的时区。
为您补充阅读: