我让struct name 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();
}
}
我的问题:有最简单的方法来实现这个比结构?和这个结构有异常,当我保存在数据库导致实体框架工作,所以我每次使用struct都需要做映射,我怎样才能用简洁的方式做映射?
几点:
-
小心你的命名。名称为
DateTimeZone
的对象可能只包含1)时区信息,或者2)日期、时间和时区。您的对象只是DateTime
的封装包装器,所以它不是这两种情况。 -
隐式操作可能是邪恶的-特别是如果它们改变了您正在处理的值的含义。我不建议将它们与日期/时间一起使用,除非你真的知道自己在做什么。这个对象的用户很快就会弄不清楚你实际使用的是什么值。
-
ToUniversalTime
和ToLocalTime
函数根据分配给您正在使用的DateTime
对象的.Kind
属性的DateTimeKind
改变其行为。您似乎正在创建一个API,其中DateTime
始终是本地的,DateTimeZone
始终是UTC的,但DateTimeKind
将阻碍这种想法。 -
正如评论中提到的,你可能会考虑使用Noda Time,这是一个非常可靠和深思熟虑的API。在Noda Time中,
Instant
类型总是表示UTC,LocalDateTime
类型总是表示无时区的日期和时间。时区由DateTimeZone
表示(请参阅与您的名称的冲突),ZonedDateTime
类型将它们组合在一起,这样您就可以同时拥有即时信息、本地时间信息和相关的时区。 -
你提到了实体框架。不幸的是,EF不能直接与您的自定义对象或野田时间一起工作。它不具备进行简单类型转换的能力。这已被要求,但尚未执行。您可以按照这里的工作项进行操作。您可以使用的一种解决方法是"好友属性",如下所述。它们并不有趣,但很有效。主要是。
-
您可能会发现合理的只是使用
DateTime
,并在需要时手动调用ToUniversalTime
或ToLocalTime
等方法。如果您希望EF在从数据库加载时正确设置DateTimeKind
,请参阅此答案。 -
请记住,
ToUniversalTime
和ToLocalTime
都与计算机的本地时区一起工作,代码恰好在该时区运行。这对于桌面和移动应用程序来说很好,但对于web应用程序来说很少需要,因为更改服务器的时区可能会极大地影响数据。考虑通过内置的TimeZoneInfo
类或Noda time中的DateTimeZone
类使用指定的时区。
附加阅读:
- 夏令时和时区最佳实践
- 时区标签wiki
也许你应该试试这个:
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;