2011-05-02 44 views
5

-Quiero convertir el tiempo de serie de Matlab (datenum, como en t_matlab=now)
a C# Fecha y hora (como en var t_cs = DateTime.Now.Ticks).Convertir Matlab Datenum a Datetime

¿Alguna idea de cómo hacerlo?

[Editar] Encontré una manera de hacerlo, pero todavía no estoy seguro si es la mejor manera.
[Editar2] Corregido el incorrecto DateTimes, gracias Jonas!

function cstime = datenum2datetime(matlabSerialTime) 
%Convert matlab serial time (datenum) to .net datenum. 
% 
% Example: 
% ntTime = datenum2datetime(now) 
% cstime = datenum2datetime([734539.4717013890 734539.5051388888]); 
% 
% See also datenum. 

% using System.DateTime.Parse(string).Ticks to convert to DateTime format. 
% t1 = now; t2 = now+1; matlab_times = [t1 t2]; 
% cs_times = [System.DateTime.Parse(datestr(t1)).Ticks ... 
%   System.DateTime.Parse(datestr(t2)).Ticks] 
% aver = diff(cs_times)/diff(matlab_times); 
% offver = cs_times(1) - matlab_times(1)*aver; 

a = 10^7*60*60*24; 
offset = -367*10^7*60*60*24; 
cstime = a*matlabSerialTime + offset; 
+1

En caso de que todavía utilice la función anterior en cualquier lugar, asegúrese de leer mi respuesta actualizada (y la respuesta de jbarr que me señaló el problema). ** ¡Su código actual está desactivado en 86 días! ** –

Respuesta

5

Editar: Sorprendido por la respuesta de Jarr que investigarse más a fondo. Resulta que los puntos de tiempo de ejemplo sharhar_m da en la pregunta son incorrectos (lo siento por no haber verificado eso antes).

En resumen, la función dada en la pregunta está desactivada de 367-281 = 86 días y deben ser corregidos a

function cstime = datenum2datetime(matlabSerialTime) 
cstime = 10^7*60*60*24*(matlabSerialTime - 367); 

Ahora a los detalles, en el caso Alguien está interesado: Usted reclama

% {05-Feb-2011 11:19:15} en System.DateTime es 6 34399319550000000

pero en MATLAB R2010b

sdt =System.DateTime(634399319550000000); 
[sdt.Day sdt.Month] 

vuelve [2 5], por lo que su valor DateTime es en realidad para el 2 de mayo no Feb 5 ª !! Para calcular los valores correctos, establezca

cs_times = [System.DateTime.Parse('05-Feb-2011 11:19:15').Ticks ... 
      System.DateTime.Parse('05-Feb-2011 12:07:24').Ticks] 

que da [634325015550000000 634325044440000000].

unidad de escalado en el tiempo

Su factor de a es 10^7 * 60 * 60 * 24 es decir, las tiendas de MATLAB la fecha/hora en las unidades de "día" (con el tiempo como días fraccionarios) y C# tiendas tiempo como "ticks", es decir, el número de "10^-7 segundos". Probablemente pueda evitar algunos errores de redondeo introduciendo el valor preciso para a.

diferencia en el punto de tiempo de referencia

El desplazamiento b expresado en días (b/a) le dice que su "origen del tiempo" es de 367 días de diferencia; con su valor anterior para b esto salió a 281 días. La documentación de MATLAB para datestr afirma

"Un número de fecha serie representa la conjunto y número fraccionario de días de 1-Ene-0000 a una fecha específica. el año 0000 no es más que un punto de referencia y es no pretende ser interpretado como un año real en el tiempo."

(a pesar de correr datestr(0,'dd-mm-yyyy HH-MM-SS') revela que el punto de referencia es en realidad 0-Ene-0000). C# ticks son el

" número de intervalos de 100 nanosegundos que han transcurrido desde 12:00 : 00 medianoche, 1 de enero de 0001, que representa DateTime.MinValue. No no incluye el número de garrapatas que son atribuibles a saltar segundos."

Así que en resumen, el 'origen en el tiempo' entre ambos sistemas se diferencia por un salto año y un día, por lo tanto, 367 días. Si realmente quisiera lidiar con fechas reales que datan de hace mucho tiempo, tendría que tomar la reforma Gregorian calendar y la corrección de Augustus a la aplicación incorrecta de años bisiestos en el Julian calendar antes del año 8 en cuenta ... pero dudo que esto sea de interés aquí ;-).

2

Use esto para convertir el número de serie de Matlab en System.DateTime ticks:

function datetimeticks = mt2dt(matlabserialtime) 
    datetimeticks = (matlabserialtime - 367)*86400/1e-7; 
end 

Y un ejemplo (en Matlab):

mdt = datenum('8/6/1901 07:50:13'); 
sdt = System.DateTime(mt2dt(mdt)); 

>> sdt.ToString 

ans = 

8/6/1901 07:50:13 

La conversión homólogo de System.DateTime a Matlab fecha número de serie es igual de fácil:

function matlabserialtime = dt2mt(datetimeticks) 
    matlabserialtime = double(datetimeticks) * 1e-7/86400 + 367; 
end 

Y un ejemplo (en Matlab):

sdt = System.DateTime.Parse('8/6/1901 07:50:13'); 
mdt = datenum(dt2mt(sdt.Ticks)); 

>> datestr(mdt) 

ans = 

06-Aug-1901 07:50:13 

Tenga en cuenta que pierde la información de DateTimeKind una vez que co nvertido a Matlab desde los tics de DateTime.
Es posible que desee aferrarse a eso y luego utilizarlo con SpecifyKind o DateTime ctor.