111111 end
112112 end
113113 elseif strcmp(type , ' isodatetime' )
114- assert(ischar(val )...
115- || iscellstr(val )...
116- || isdatetime(val ) ...
117- || (iscell(val ) && all(cellfun(' isclass' , val , ' datetime' ))),...
118- errid , errmsg );
114+ addpath(fullfile(fileparts(which(' NwbFile' )), ' external_packages' , ' datenum8601' ));
115+ assert(ischar(val ) || iscellstr(val ) || isdatetime(val ) || ...
116+ (iscell(val ) && all(cellfun(' isclass' , val , ' datetime' ))), errid , errmsg );
119117 if ischar(val ) || iscellstr(val )
120118 if ischar(val )
121119 val = {val };
122120 end
123121
124122 datevals = cell(size(val ));
123+ % one of:
124+ % +-hh:mm
125+ % +-hhmm
126+ % +-hh
127+ % Z
128+ tzre_pattern = ' (?:[+-]\d{2}(?::?\d{2})?|Z)$' ;
125129 for i = 1 : length(val )
126- datevals{i } = datetime8601(val{i });
130+ dnum = datenum8601(val{i });
131+
132+ tzre_match = regexp(val{i }, tzre_pattern , ' once' );
133+ if isempty(tzre_match )
134+ tz = ' local' ;
135+ else
136+ tz = val{i }(tzre_match : end );
137+ if strcmp(tz , ' Z' )
138+ tz = ' UTC' ;
139+ end
140+ end
141+ datevals{i } = ...
142+ datetime(dnum(1 ), ' TimeZone' , tz , ' ConvertFrom' , ' datenum' );
127143 end
128144 val = datevals ;
129145 end
132148 val = {val };
133149 end
134150
135- for i = 1 : length(val )
151+ for i= 1 : length(val )
136152 if isempty(val{i }.TimeZone)
137153 val{i }.TimeZone = ' local' ;
138154 end
171187 val = truval ;
172188 end
173189end
174- end
175-
176- function date_time = datetime8601(datestr )
177- addpath(fullfile(fileparts(which(' NwbFile' )), ' external_packages' , ' datenum8601' ));
178- [~ , ~ , format ] = datenum8601(datestr );
179- format = format{1 };
180- has_delimiters = format(1 ) == ' *' ;
181- if has_delimiters
182- format = format(2 : end );
183- end
184-
185- assert(strncmp(format , ' ymd' , 3 ),...
186- ' MatNWB:Types:Util:CheckDType:DateTime:Unsupported8601' ,...
187- ' non-ymd formats not supported.' );
188- separator = format(4 );
189- if separator ~= ' '
190- % non-space digits will error when specifying import format
191- separator = [' '' ' separator ' '' ' ];
192- end
193-
194- has_fractional_sec = isstrprop(format(8 : end ), ' digit' );
195- if has_fractional_sec
196- seconds_precision = str2double(format(8 : end ));
197- if seconds_precision > 9
198- warning(' MatNWB:Types:Util:CheckDType:DateTime:LossySeconds' ,...
199- [' Potential loss of time data detected. MATLAB fractional seconds ' ...
200- ' precision is limited to 1 ns. Extra precision will be truncated.' ]);
201- end
202- end
203- day_segments = {' yyyy' , ' MM' , ' dd' };
204- time_segments = {' HH' , ' mm' , ' ss' };
205-
206- if has_delimiters
207- day_delimiter = ' -' ;
208- time_delimiter = ' :' ;
209- else
210- day_delimiter = ' ' ;
211- time_delimiter = ' ' ;
212- end
213-
214- day_format = strjoin(day_segments , day_delimiter );
215- time_format = strjoin(time_segments , time_delimiter );
216- format = [day_format separator time_format ];
217- if has_fractional_sec
218- format = sprintf(' %s .%s ' , format , repmat(' S' , 1 , seconds_precision ));
219- end
220-
221- [datestr , timezone ] = derive_timezone(datestr );
222- date_time = datetime(datestr ,...
223- ' InputFormat' , format ,...
224- ' TimeZone' , timezone );
225- end
226-
227- function [datestr , timezone ] = derive_timezone(datestr )
228- % one of:
229- % +-hh:mm
230- % +-hhmm
231- % +-hh
232- % Z
233- tzre_pattern = ' (?:[+-]\d{2}(?::?\d{2})?|Z)$' ;
234- tzre_match = regexp(datestr , tzre_pattern , ' once' );
235- if isempty(tzre_match )
236- timezone = ' local' ;
237- else
238- timezone = datestr(tzre_match : end );
239- if strcmp(timezone , ' Z' )
240- timezone = ' UTC' ;
241- end
242- datestr = datestr(1 : (tzre_match - 1 ));
243- end
244190end
0 commit comments