Skip to content

Document every type conversion on reading - #280

Merged
matthijscox merged 8 commits into
JuliaIO:masterfrom
Thenewmanator15:docs-types
Oct 27, 2026
Merged

matthijscox merged 8 commits into
JuliaIO:masterfrom
Thenewmanator15:docs-types

Conversation

@Thenewmanator15

Copy link
Copy Markdown
Contributor

Builds on #255 (which carries the timetable change from #253): this branch is #255 plus one commit, so please merge it after #253 and #255. Until then GitHub shows their commits here too.

docs/src/types.md listed seven MATLAB types and a few converted classes. This fills it in, for reading:

  • The main table now covers complex, logical and sparse arrays, char arrays with several rows (a Vector{String}, one string per row), function handles (readable, but not callable) and arrays of objects.
  • The details that catch people out: a scalar stays a 1×1 matrix in v4 files; empty arrays keep their type and size; a single character is a Char from a v7.3 file but a String from older ones; char rows keep MATLAB's padding; a handle object referred to twice reads as one object.
  • For the converted classes, what is kept and what is not: a categorical loses whether it is ordinal, a table its row names and properties. The table and convert_opaque keywords are explained, and category is corrected to categorical.
  • The classes that are not converted (calendarDuration, containers.Map, dictionary and your own classes), and that enumerations are not supported.

The timetable and time zone text from #253 and #255 is kept as it is, and the datetime notes link to its Time zones section.

Checks. Each statement about current behaviour was checked against master with files saved from MATLAB R2025a in v4, v7 and v7.3. The docs build with docs/make.jl, and the Time zones link resolves.

🤖 Generated with Claude Code

Thenewmanator15 and others added 6 commits September 25, 2026 21:41
A timetable was returned as a MatlabOpaque, its parts decoded but not assembled.
It now becomes a table (MatlabTable by default, or the `table` type) whose first
column holds the row times, named after the row dimension ("Time" unless renamed),
followed by the variables.

Row times are stored one per row (datetime or duration, already converted to
DateTime or Millisecond), or, for a regular timetable, as a start time and a sample
rate or time step; those are generated. A timetable stepped in calendar units has
no fixed rate and is left as the MatlabOpaque, with a warning. `table=Nothing`
keeps the raw object, as for tables.

test/timetable_gen.m writes test/v7 and test/v7.3/timetable.mat: datetime and
duration row times, sample rate, time step from a datetime start, an empty
timetable, a two-column variable, a renamed row dimension, calendar months. The
.mat files are not included; the timetable tests are skipped until they are
generated in MATLAB and committed.
MATLAB stores a datetime with a time zone as its UTC instant plus the zone's name.
The zone was dropped with a warning, leaving the UTC instant as a DateTime. With
TimeZones.jl loaded (Julia 1.9+, package extension MATTimeZonesExt), it is now a
ZonedDateTime in its zone: an IANA name, "UTC", or a fixed offset such as "+05:30".
Without TimeZones.jl, and on older Julia, the result is unchanged (the UTC instant),
with a warning that says so and names the package. A zone TimeZones.jl does not
recognise falls back to the UTC instant, with a warning.

"UTCLeapSeconds" counts leap seconds, which neither DateTime nor ZonedDateTime can
represent; it was returned as a DateTime 26 s off (2016-12-31T23:59:60 read as
2017-01-01T00:00:26) and is now left as the MatlabOpaque, with a warning.

A regular timetable with a zoned start now works too (the start may be any
Dates.AbstractDateTime).

test/timezone_gen.m writes test/v7 and test/v7.3/timezone.mat (Europe/London in summer
and winter, UTC, +05:30, America/New_York across DST, UTCLeapSeconds, a timetable with
zoned row times and a regular one with a zoned start). read.jl checks the file before
TimeZones.jl is loaded, the new test/timezones.jl (run last) after. The .mat files are
not included; both testsets skip until they are generated in MATLAB and committed.
TimeZones.jl is a weak dependency and a test dependency.
Conflicts:
- Project.toml: keeps the TimeZones compat entry and takes master's
  julia = "1.9".
- test/runtests.jl: keeps master's structutils.jl and runs timezones.jl
  last, as its comment requires.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
docs/src/types.md listed seven MATLAB types and a handful of converted
classes. It now covers what reading gives for complex, logical and
sparse arrays, char arrays with several rows, function handles and
arrays of objects, with the details that catch people out: scalars stay
1x1 matrices in v4 files, empty arrays keep their type and size, a
single character is a Char from v7.3 files but a String from older ones,
and handle objects stay identical.

For the converted classes it says what is kept and what is not: a
categorical loses whether it is ordinal, a table its row names and
properties. It names the classes that are not converted, and that
enumerations are not supported. `category` is corrected to
`categorical`. The timetable and time zone text from JuliaIO#253 and JuliaIO#255 is
kept, and the datetime notes point to the Time zones section.

Each statement about master was checked with files saved from MATLAB
R2025a in v4, v7 and v7.3.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Comment thread test/read.jl Resolved
Comment thread test/read.jl Resolved
@matthijscox
matthijscox merged commit 9b47fca into JuliaIO:master Oct 27, 2026
8 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants