Incongruities in InputFormat in datetime

52 views (last 30 days)
My head officially hurts.
I've got a date string: s = '2022-12-08T14:37:14.625Z' - Stupid programmers and Zulu time stamps....
It's actually an array of these but lets start simple.
I want to calculate the number of milliseconds in the string. Doesn't really matter from when. Epoch time, whatever. Just consistent so I can plot this foo-foo.
According to a plethora of posts around here and elsewhere on the web, I can do this with datetime with a format string: formatspec = 'yyyy-MM-dd''''T''''HH:mm:ss.SSS''''Z';
This gives me 'yyyy-MM-dd''T''HH:mm:ss.SSS''Z' for formatspec.
So I plug this into datetime, with s:
d = datetime(s,'ImportFormat', formatspec);
Matlab spits in my face and says "The format 'yyyy-MM-dd' 'T' 'HH:mm:ss.SSS' 'Z' contains an unsupported symbol: 'T'...."
Ok, but if I do it this way it accepts it: d = datetime(s,'ImportFormat', 'yyyy-MM-dd''T''HH:mm:ss.SSS''Z');
Any thoughts about why this works, but the formatspec string didn't would be greatly appreciated.
And any ideas about a really efficient way to get the number of milliseconds out of s = '2022-12-08T14:37:14.625Z' would probably get you an adult beverage of your choice!
bent

Accepted Answer

Bently
Bently on 21 Dec 2022
Thanks.
Interesting situation.
hms provides the correct answer.
However, I did the brute force approach, which got me to the goal line.
From the original date string, I picked out the hours, minutes, and seconds using extractbetween() and then the rest was trivial.
Our current installed release is 2022a. That only took me 18 months to get installed, so upgrading might not be the most expedient solution.
Appreciate all the feedback.
Lets consider the topic closed!
bent

More Answers (4)

Steven Lord
Steven Lord on 21 Dec 2022
You have a few too many single quotes.
formatspec1 = 'yyyy-MM-dd''''T''''HH:mm:ss.SSS''''Z'
formatspec1 = 'yyyy-MM-dd''T''HH:mm:ss.SSS''Z'
formatspec2 = 'yyyy-MM-dd''T''HH:mm:ss.SSS''Z'
formatspec2 = 'yyyy-MM-dd'T'HH:mm:ss.SSS'Z'
Let's try converting your date string with each of those formats.
s = '2022-12-08T14:37:14.625Z';
try
dt1 = datetime(s, 'InputFormat', formatspec1)
catch ME
fprintf("Error: %s\n", ME.message)
end
Error: The format 'yyyy-MM-dd''T''HH:mm:ss.SSS''Z' contains an unsupported symbol: 'T'. See the datetime.Format property for a complete description of the identifiers used in datetime formats.
try
dt2 = datetime(s, 'InputFormat', formatspec2)
catch ME
fprintf("Error: %s\n", ME.message)
end
dt2 = datetime
08-Dec-2022 14:37:14
But I'd skip the whole single quotes inside single quotes issue and store the format as a string. To write a single quote character inside a string just use '.
formatspec3 = "yyyy-MM-dd'T'HH:mm:ss.SSS'Z"
formatspec3 = "yyyy-MM-dd'T'HH:mm:ss.SSS'Z"
dt3 = datetime(s, 'InputFormat', formatspec3)
dt3 = datetime
08-Dec-2022 14:37:14

Star Strider
Star Strider on 20 Dec 2022
Edited: Star Strider on 20 Dec 2022
For those sort of formats, use 'uuuu' instead of 'yyyy'. (This should be more thorougly discussed in the documentation to avoid frustrations such as what you’re experiencing.)
Try something like this —
s = '2022-12-08T14:37:14.625Z'
s = '2022-12-08T14:37:14.625Z'
DT = datetime(s, 'InputFormat','uuuu-MM-dd''T''HH:mm:ss.SSS''Z''', 'TimeZone','UTC', 'Format','yyyy-MM-dd HH:mm:ss.SSS')
DT = datetime
2022-12-08 14:37:14.625
Setting the 'TimeZone','UTC' is important. You can redefine it to local time iff necessary.
EDIT — Corrected typographical errors.
.

the cyclist
the cyclist on 20 Dec 2022
I don't think you wrote the formatspec correctly. Is this what you want?
s = '2022-12-08T14:37:14.625Z';
formatspec = 'yyyy-MM-dd''T''HH:mm:ss.SSS''Z''';
d = datetime(s,'InputFormat', formatspec)
d = datetime
08-Dec-2022 14:37:14
  2 Comments
Bently
Bently on 21 Dec 2022
Moved: the cyclist on 21 Dec 2022
Argh....
The documentation for 'InputFormat' is very clear that it 'yyyy-MM-dd''T''HH:mm:ss.SSS''Z' is the correct format.
Doing it your way; 'yyyy-MM-dd''T''HH:mm:ss.SSS''Z''' produces a positive result.
Thank you,
bent
the cyclist
the cyclist on 21 Dec 2022
Edited: the cyclist on 21 Dec 2022
I'd be curious where specifically in the docs you found a discrepancy. I don't see your exact case in the list of examples here, and I expect you may have just inferred something incorrectly.
All I really did was be careful to correctly using two single-quote characters on each side of the T and Z, to ensure that these the constructed character array had one single-quote character on each side:
'before stuff ... ''T'' ... middle stuff ... ''Z'' ... after stuff'
ans = 'before stuff ... 'T' ... middle stuff ... 'Z' ... after stuff'
I think this was more about me just having a better sense about the principles of constructing these kinds of character arrays. It is admittedly a bit tricky.

Sign in to comment.


Bently
Bently on 21 Dec 2022
Thanks.
Got this doing it's thing....
But something is rotten in Denmark.
Using the stuff from above, I've got a time: dtime="2022-12-08 14:59:59.925"
Doing some data extraction so I can calcumate milliseconds:
hour(dtime) = 14 -> great!
minute(dtime) = 60 -> What?
seconds(dtime) = 59.920 -> great!
Any ideas as to why the minute is 60 and not 59?
thanks
bent
  2 Comments
the cyclist
the cyclist on 21 Dec 2022
Can you post a functioning code snippet that gives this result? The way you have defined dtime here, it is a string, not a datetime. I would be particularly wary of this sentence from the documentation:
"To support existing code that previously required Financial Toolbox™, minute also accepts serial date numbers and text as inputs, but they are not recommended".
Note:
dtime="2022-12-08 14:59:59.925"; % String input
minute(dtime)
ans = 60
dtime=datetime("2022-12-08 14:59:59.925"); % Proper datetime input
minute(dtime)
ans = 59
Star Strider
Star Strider on 21 Dec 2022
It works correctly in R2022b.
Perhaps upgrading is an option?
dtime="2022-12-08 14:59:59.925";
DT = datetime(dtime, 'InputFormat','yyyy-MM-dd HH:mm:ss.SSS', 'Format','yyyy-MM-dd HH:mm:ss.SSS')
DT = datetime
2022-12-08 14:59:59.925
mmv = minute(DT)
mmv = 59
ssv = second(DT)
ssv = 59.9250
[h,m,s] = hms(DT)
h = 14
m = 59
s = 59.9250
.

Sign in to comment.

Tags

Products


Release

R2022a

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!