Creo que esta es una excelente pregunta. (Acabo descubierto.)
A menos que usted está operando con fechas muy cercanas al 1900, un DateTime
tendrá un mayor precisión que una fecha de OA. Pero por alguna razón oscura, los autores de la estructura DateTime
solo aman para truncar al milisegundo entero más cercano cuando convierten entre DateTime
y algo más. Huelga decir que hacer esto arroja mucha precisión sin una buena razón.
Aquí es una solución alternativa:
static readonly DateTime oaEpoch = new DateTime(1899, 12, 30);
public static DateTime FromOADatePrecise(double d)
{
if (!(d >= 0))
throw new ArgumentOutOfRangeException(); // NaN or negative d not supported
return oaEpoch + TimeSpan.FromTicks(Convert.ToInt64(d * TimeSpan.TicksPerDay)):
}
public static double ToOADatePrecise(this DateTime dt)
{
if (dt < oaEpoch)
throw new ArgumentOutOfRangeException();
return Convert.ToDouble((dt - oaEpoch).Ticks)/TimeSpan.TicksPerDay;
}
Ahora, vamos a considerar (de su pregunta) la DateTime
dada por:
var ourDT = new DateTime(634202170964319073);
// .ToSting("O") gives 2010-09-16T06:58:16.4319073
La precisión de cualquier DateTime
es de 0,1 mu s.
cerca de la fecha y la hora que estamos considerando, la precisión de una fecha de la OA es:
Math.Pow(2.0, -37.0)
días, o alrededor de 0.6286
microsiemens
Llegamos a la conclusión de que en esta región una DateTime
es más preciso que una fecha OA por (un poco) un factor seis.
Convirtamos ourDT
a double
usando mi método de extensión por encima de
double ourOADate = ourDT.ToOADatePrecise();
// .ToString("G") gives 40437.2904679619
// .ToString("R") gives 40437.290467961888
Ahora, si convierte ourOADate
de nuevo a un DateTime
utilizando el método estático FromOADatePrecise
anterior, se obtiene
2010-09-16T06:58:16.4319072
(escrito con "O"
formato)
Comparando con el original, vemos que la pérdida de precisión es en este caso 0.1 μs. Esperamos que la pérdida de precisión esté dentro de ± 0.4 μs ya que este intervalo tiene una longitud de 0.8 μs que es comparable a los 0.6286 μs mencionados anteriormente.
Si nos vamos a la inversa, comenzando con un double
que representa una fecha de OA no demasiado cerca del año 1900, y primera uso FromOADatePrecise
y continuaciónToOADatePrecise
, entonces volvamos a un double
, y porque la precisión del intermedio DateTime
es superior a la de una fecha OA, esperamos un viaje de ida y vuelta perfecto en este caso. Si, por otro lado, utiliza los métodos BCL FromOADate
y ToOADate
en el mismo orden, es extremadamente improbable obtener un buen viaje de ida y vuelta (a menos que el double
que comenzamos tenga una forma muy especial).
No son exactamente las especificaciones, pero vale la pena leer esto: http://blogs.msdn.com/b/ericlippert/archive/2003/09/16/eric-s-complete-guide-to-vt-date.aspx –
Gracias, parece que hay mucha historia detrás de este formato de fecha ... –