Para nuestro caso no era práctico siempre especificar el DateTimeKind como se dijo anteriormente:
DateTime utcDateTime = DateTime.SpecifyKind(databaseDateTime, DateTimeKind.Utc);
Estamos utilizando Entity Framework, pero esto debe ser similar a Linq-to-SQL
Si desea forzar que todos los objetos DateTime que salen de la base de datos se especifiquen como UTC necesitará agregar un archivo de transformación T4 y agregar lógica adicional para todos los objetos DateTime y anulable DateTime de tal manera que son inicializadas como DateTimeKind.Utc
que tienen un blog que explica paso a paso: http://www.aaroncoleman.net/post/2011/06/16/Forcing-Entity-Framework-to-mark-DateTime-fields-at-UTC.aspx
En resumen:
1) Crear el archivo .tt para su modelo .edmx (o .dbml para Linq-to-SQL)
2) Abra el archivo .tt y encuentre el método "WritePrimitiveTypeProperty".
3) Reemplace el código del colocador existente. Esto es todo lo que entre el ReportPropertyChanging
y los ReportPropertyChanged
devoluciones de llamada de método con lo siguiente:
<#+ if(((PrimitiveType)primitiveProperty.TypeUsage.EdmType).PrimitiveTypeKind == PrimitiveTypeKind.DateTime)
{
#>
if(<#=code.FieldName(primitiveProperty)#> == new DateTime())
{
<#=code.FieldName(primitiveProperty)#> = StructuralObject.SetValidValue(value<#=OptionalNullableParameterForSetValidValue(primitiveProperty, code)#>);
<#+
if(ef.IsNullable(primitiveProperty))
{
#>
if(value != null)
<#=code.FieldName(primitiveProperty)#> = DateTime.SpecifyKind(<#=code.FieldName(primitiveProperty)#>.Value, DateTimeKind.Utc);
<#+ }
else
{#>
<#=code.FieldName(primitiveProperty)#> = DateTime.SpecifyKind(<#=code.FieldName(primitiveProperty)#>, DateTimeKind.Utc);
<#+
}
#>
}
else
{
<#=code.FieldName(primitiveProperty)#> = StructuralObject.SetValidValue(value<#=OptionalNullableParameterForSetValidValue(primitiveProperty, code)#>);
}
<#+
}
else
{
#>
<#=code.FieldName(primitiveProperty)#> = StructuralObject.SetValidValue(value<#=OptionalNullableParameterForSetValidValue(primitiveProperty, code)#>);
<#+
}
#>
Dado que UTC es una zona horaria conocido, es más rápido usar DateTime.SpecifyKind. Si se sabe que TimeZone no es el TimeZone local actual ni el UTC (por ejemplo, servidores DB en EST y servidores de aplicaciones en PST), ese sería el único momento en el que preferiría utilizar TimeZoneInfo. –