Is there a way that I can instruct Entity Framework to always store DateTimeOffset as the UTC value. Technically there is no reason for this but I prefer it if all the data in my database is consistent.
Currently it is storing the DateTimeOffset as received from the client which could be anything depending on the users locale.
I was thinking of perhaps intercepting all the SaveChanges method, looping through the changes, looking for DateTimeOffset types and doing the conversion explicitly, but this seems like a lot of work which could be mitigated if EntityFramework has something built in.
Any insight or suggestions would be greatly appreciated.
EDIT: The difference between my post and others dealing with this topic is that my C# property is of type DateTimeOffset and my database field is also DateTimeOffset(0). There is not technical reason to convert other than consistency. If I store a value as "17:00 +5:00" or "10:00 -2:00" it doesn't matter, those are both identical moments in time. However, I would like to have all my dates stored as "12:00 +0:00" so that it is easier to read in SSMS or other DB tools.
EDIT 2: Seeing as there doesn't seem to be "simple" way to do this I am looking to now tackle the problem in the DbContext.SaveChanges() function. The problem is that no matter what I do, the value won't change? Here's the code so far:
public new void SaveChanges()
{
foreach (var entry in this.ChangeTracker.Entries())
{
foreach (var propertyInfo in entry.Entity.GetType().GetProperties().Where(p => p.CanWrite && p.PropertyType == typeof(DateTimeOffset)))
{
var value = entry.CurrentValues.GetValue<DateTimeOffset>(propertyInfo.Name);
var universalTime = value.ToUniversalTime();
entry.CurrentValues[propertyInfo.Name] = universalTime;
// entry.Property(propertyInfo.Name).CurrentValue = universalTime;
// Adding a watch to "entry.CurrentValues[propertyInfo.Name]" reveals that it has not changed??
}
// TODO: DateTimeOffset?
}
base.SaveChanges();
}
EDIT 3 I finally managed to solve this, see answer below
datetimeoffset
. Why do you think you need to convert the value and lose the original offset information? There is no consistency to maintain here, just data loss. – HasanpropertyInfo.SetValue(entry.Entity, universalTime)
)?. I don't think I've ever tried mangling withCurrentValues
– Jacobindatetimeoffset
if you discard the offset then? Furthermore, from a human/developer perspective, something that magically changes values and discards data is not appreciated. It's far cleaner to change the offset when setting the property, not behind scenes – HasanDateTimeOffset
in the UTC timezone other than "it looks prettier on SSMS". If you need to show them in a specific timezone, convert them for display (in your application), not for storing. – Jacobindatetimeoffset
fields in SQL Server at least, is stored, indexed, and compared in UTC always. The offset is just there for retrieval (so that you know which timeoffset the data was entered in). Comparisons are always made in UTC – JacobinThe data is stored in the database and processed, compared, sorted, and indexed in the server as in UTC. The time zone offset will be preserved in the database for retrieval.
. Basically, it doesn't matter for anything other than "display" – Jacobin