MAT.jl icon indicating copy to clipboard operation
MAT.jl copied to clipboard

Variables of type duration, datetime, categorical, and table created in MATLAB 2024b cannot be read.

Open ZhuWenhao-88 opened this issue 1 month ago • 9 comments

I created some variables of types such as duration, datetime, categorical, and table using MATLAB and saved them as .mat files. The files were created and saved using MATLAB 2020b. They can be read normally using the latest master branch's MAT.jl, but MATLAB 2024b and maltab 2025b will report errors (the problem with string types in the master branch has been fixed).

Image Image Image

create_data.txt julia_test_data_2020b.txt julia_test_data_2024b.txt julia_test_data_2025b.txt

ZhuWenhao-88 avatar Dec 01 '25 03:12 ZhuWenhao-88

the datetime variable inside 2020b and 2024b are using different format or precision, in 2020b, the datenum field is saved in 7 bytes, while 2024b using 8 + 3 bytes. that's pretty strange.

  1. why the precision is different between 2020b and 2024b, @ZhuWenhao-88 are you using the same command: dt_scalar = datetime('now'); to generate the dt_scalar?

  2. what's the purpose of matlab 2024 using the extra 3 bytes , in the array flags, the 2020b is 06 while 2024b is 06 08.

  3. for the MAT.jl, I think the current code logic didn't forsee the two double data element within a 1*1 matrix, so it interpet both of the data element caused the error. Again, this matlab newer design is weired!!!

MegaShark1911 avatar Dec 01 '25 05:12 MegaShark1911

Yes, I used the same code, and the 'm' code was created in the create_data file.

ZhuWenhao-88 avatar Dec 01 '25 05:12 ZhuWenhao-88

The issue is only with datetime in the newer versions, or other types as well?

foreverallama avatar Dec 01 '25 13:12 foreverallama

I think only with newer version datetime, didn't check the other mcos type for details

MegaShark1911 avatar Dec 01 '25 14:12 MegaShark1911

Yeah, looks to be only in datetime. I don't understand how MATLAB is encoding data - some kind of precision is definitely stored in the complex part, but what?

Anyways, in MAT_types.jl, ms_rem after division is returning a float in your example with the variable dt_scalar. So

s, ms_rem = fldmod(ms, 1_000)  # whole seconds and remainder milliseconds

So Millisecond(ms_rem) is throwing an error:

return DateTime(1970, 1, 1) + Second(s) + Millisecond(ms_rem)

A temporary fix would be to round ms_rem to an integer. Some precision would be lost I guess in sub-ms. Does that sound okay?

Would be good to have a long-term fix in the meantime if someone can figure out exactly what's going on here

foreverallama avatar Dec 01 '25 14:12 foreverallama

I used MATLAB 2024b to save a .mat file, and tested four data types: duration, datetime, categorical, and table, but none of them could be read correctly.

ZhuWenhao-88 avatar Dec 02 '25 00:12 ZhuWenhao-88

So there seems to be 2 different problems here:

  1. This is related to #212 and is because of an update to how MATLAB is writing metadata in MAT-files, particularly for saved dynamic properties. I have pushed a perma fix for it in #216

  2. The other issue is related to datetime. Particularly with how MATLAB is storing precision information. The fix in #216 is temporary and should resolve errors, but results in a loss of precision. Will need to study exactly how MATLAB is handling this to resolve it

foreverallama avatar Dec 02 '25 08:12 foreverallama

@ZhuWenhao-88 Could you share a MAT-file from the newer versions with the following script:

var1 = "hello";
var2 = datetime;
var3 = "goodbye";
var4 = timetable(datetime, 1);
var5 = datetime;
var6 = MyClass();
var7 = datetime;

where MyClass.m has the following definition:

classdef MyClass
    properties
        a
    end
    methods
        function obj = MyClass
            obj.a = 10;
        end
        function s = saveobj(obj)
            s.somefield = obj.a;
        end
   end
end

foreverallama avatar Dec 02 '25 17:12 foreverallama

I've created the test file for you (renamed to .txt for github)

var1 = "hello";
var2 = datetime;
var3 = "goodbye";
var4 = timetable(datetime, 1);
var5 = datetime;
var6 = MyClass();
var7 = datetime;
save('R2024b_test.mat', 'var1', 'var2', 'var3', 'var4', 'var5', 'var6', 'var7')

R2024b_test.txt

matthijscox avatar Dec 05 '25 13:12 matthijscox