Конвертировать Matlab Datenum в Datetime - PullRequest
5 голосов
/ 02 мая 2011

-Я хочу преобразовать последовательное время Matlab (datenum, как в t_matlab=now)
до c # Datetime (как в var t_cs = DateTime.Now.Ticks).

Есть идеи, как это сделать?

[Редактировать] Я нашел способ сделать это, но все еще не уверен, что это лучший способ.
[Edit2] Исправлено неправильное DateTimes, спасибо Джонас!

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;

Ответы [ 2 ]

5 голосов
/ 02 мая 2011

Редактировать : Удивлен ответом Джарра, который я исследовал дальше. Оказывается, что примерные моменты времени, которые sharhar_m дает в вопросе, неверны (извините, что не проверял это ранее).

В итоге , функция, заданная в вопросе , отключена на 367-281 = 86 дней и должна быть исправлена ​​на

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

Теперь перейдем к деталям, если кому-то это интересно: Вы заявляете

% {05-Фев-2011 11:19:15} в System.DateTime: 634399319550000000

но в MATLAB R2010b

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

возвращает [2 5], поэтому ваше значение DateTime на самом деле для 2 мая, а не 5 февраля !! Для расчета правильных значений установите

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

, что дает [634325015550000000 634325044440000000].

Масштаб единицы времени

Ваш коэффициент a равен 10 ^ 7 * 60 * 60 * 24, т. Е. MATLAB хранит дату / время в единицах «дни» (со временем как дробные дни), а C # сохраняет время как «галочки», то есть число « 10 ^ -7 секунд ". Вероятно, вы можете избежать некоторых ошибок округления, введя точное значение для a.

Разница в контрольной точке времени

Смещение b, выраженное в днях (b/a), говорит о том, что их «происхождение времени» составляет 367 дней; с вашим старым значением b получилось 281 день. Документация MATLAB для datestr состояний

"Серийный номер даты представляет целое и дробное число дней с 1 января по 0000 до определенной даты. 0000 год - это просто ссылка точка и не предназначена для интерпретируется как реальный год во времени. "

(даже при запуске datestr(0,'dd-mm-yyyy HH-MM-SS') обнаруживается, что контрольная точка на самом деле 0-Jan-0000). C # галочки являются

"количество интервалов 100 наносекунд прошедшие с 12:00:00 полночь 1 января 0001 года, которая представляет DateTime.MinValue. Оно делает не включает количество тиков, которые относятся к високосным секундам. "

Итак, в итоге, «происхождение во времени» между обеими системами отличается на один високосный год и один день, следовательно, 367 дней. Если вы на самом деле хотели иметь дело с реальными датами, которые были бы в далеком прошлом, вам пришлось бы принять григорианский календарь реформу и поправку Августа к неправильному применению високосных годов в юлианском календаре до 8 год в счет ... но я сомневаюсь, что это здесь интересно; -).

2 голосов
/ 20 августа 2011

Используйте это для преобразования серийного номера даты Matlab в тики System.DateTime:

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

И пример (в Matlab):

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

>> sdt.ToString

ans = 

8/6/1901 07:50:13

Аналогичное преобразование из серийного номера даты в System.DateTime в Matlab также просто:

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

И пример (в 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

Обратите внимание, что вы теряете информацию DateTimeKind после преобразования в Matlab из тиков DateTime.
Вы можете придерживаться этого, а затем использовать его вместе с SpecifyKind или DateTime ctor.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...