You are now following this question
- You will see updates in your followed content feed.
- You may receive emails, depending on your communication preferences.
Datetimes don't seem to be recognised
4 views (last 30 days)
Show older comments
Can anyone explain to me why this isn't working? For some reason, the datetime t is not recognised as occurring between times.t1.start and times.t1.end, even though it DOES! It is recognised as occurring after t1.start, but not before t1.end.
isbetween() also does not work so I am guessing I have overlooked something simple...
start=datetime(2021,08,11,09,58,25);
last=datetime(2021,08,11,10,01,00);
t=gps.DateTime(ii) %reading same datetime from my table
t=datetime(2021,08,11,09,59,25)
%if vessel position time occurs during particular transect working on
if (t>=start)&&(t<last)
%append it to specific part of structure
disp('It works!')
else
disp('It does not work')
end
%Datetime from my table:
t =
datetime
11-Aug-2021 09:59:25
%Datetime datetime(2021,08,11,09,59,25)
t =
datetime
11-Aug-2021 09:59:25
Accepted Answer
Star Strider
on 10 Nov 2021
I’m not certain what you’re doing and I can’t run the posted code. I’m also not certain what the actual problem is.
.
20 Comments
Louise Wilson
on 10 Nov 2021
Sorry, I have amended the code above. Basically, it works if I manually enter the datetime, but if I pull the same datetime from a table, it doesn't work, even though the values look the same? What could be wrong?
Star Strider
on 10 Nov 2021
I’m guessing here, however be certain that the ‘datetime’ from the table is actually a datetime array and not a string or character array the just looks like a datetime array.
a = '11 Nov 1918 11:00:00';
b = datetime('11 Nov 1918 11:00:00', 'InputFormat','dd MMM yyyy HH:mm:ss');
whos a b
Name Size Bytes Class Attributes
a 1x20 40 char
b 1x1 8 datetime
They may appear to be the same however are not. Sometimes, readtable will read a character array as a character array if it does not recognise the format, so it will not be converted automatically to an actual datetime array. (That was actually the situation in this illustration, and the reason I added the 'InputFormat' name-value pair, when it failed the first time to convert automatically.)
And for the record, I still believe that isbetween would be likely more efficient and robust for the if test!
.
Louise Wilson
on 10 Nov 2021
Edited: Louise Wilson
on 10 Nov 2021
Hmm, that makes sense, but I am not sure it is the case here.
>> whos(subset.DateTime(1))
Error using whos
Must be a string scalar or character vector.
Star Strider
on 10 Nov 2021
Edited: Star Strider
on 10 Nov 2021
Well, they¹re definitely datetime values. So much for that theory!
I used this code —
LD = load('Louise Wilson subset.mat');
subset = LD.subset;
start=datetime(2021,08,11,09,58,25);
last=datetime(2021,08,11,10,01,00);
TF = isbetween(subset.DateTime, start, last)
to get this result —
TF =
5×1 logical array
0
0
0
0
0
So if it’s any consolation, none of them meet the criteria.
I still can’t follow the code so I’m not certain what you’re doing, however this may be part of the problem, if these are the dates and times being compared. Nothing is actually wrong, it’s just that the dates in ‘subset.DateTime’ aren’t in the interval being tested. That may not be true for all values of a larger datetime array, however it’s true for this set.
EDIT —
The problem is that the format is different between the two sets of datetime arrays —
start.Format = dt.Format
produces —
start =
datetime
08/11/2021 09:58:25
so the days and months are reversed between the different values. The ‘subset.DateTime’ format is 'MM/dd/uuuu HH:mm:ss' and the ‘start’ and ‘end’ format is 'dd-MMM-uuuu HH:mm:ss' that being the problem. I am not certain which is the desired format so I will not convert them. Nevertheless, they all must be the same, and then the logic will work as intended. Convert them using the approach I used here, supplying the desired format string for both the comparison and ‘subset’ arrays. Then do the comparison.
.
Louise Wilson
on 10 Nov 2021
It's not true, because if you look at the actual datetime values in the table, they do occur between start and last. All of them do!
Louise Wilson
on 10 Nov 2021
Hmm, I tried that already but I must have done it wrong. Thank you so much!!
Star Strider
on 10 Nov 2021
As always, my pleasure!
.
Louise Wilson
on 10 Nov 2021
Is there by any chance a way to 'correct' the current datetime format, for example to switch month and day around?
Walter Roberson
on 10 Nov 2021
Edited: Walter Roberson
on 10 Nov 2021
You should do that at the time you read in the data into your table.
filename = 'FileNameGoesHere.txt'; %the original file not the mat file
opt = detectImportOptions(filename);
now = datetime('now');
fmt = now.Format;
opt = setvaropts(opt, 'DateTime', 'InputFormat', 'dd/MM/uuuu HH:mm:ss', 'Format', fmt);
YourData = readtable(filename, opt);
Louise Wilson
on 10 Nov 2021
Thanks, it's actually a .mat file which is huge so I wasn't sure how to go about it. I will make sure to do that from now on.
Star Strider
on 10 Nov 2021
For a .mat file, it is likely easiest to keep the format they are already in, and convert ‘start’ and ‘end’ to that format. This just make it easier to understand, removing any ambiguity.
The datetime variables are stored in a generic form that is independent of the selected format, so they won¹t change.
.
Louise Wilson
on 10 Nov 2021
Thanks, I ended up doing this, because they are the wrong way round. Learned my lesson! Don't trust American equipment for your datetime :-P
%date format is mixed up in table (month and day wrong way round)
correct_date=datetime(2021,08,11,'Format','dd/MM/yyyy');
for i=1:height(gps)
gps.DateTime(i)=correct_date+timeofday(gps.DateTime(i));
end
Star Strider
on 10 Nov 2021
That will work, however the loop may not be necessary if the times are already matching the dates and just need to be combined with the dates.
.
Walter Roberson
on 10 Nov 2021
No, it is completely unnecessary for the Format to match.
The problem is not a mismatch in format: the problem is that the data in the file has month 11 day 8 stored in it, instead of month 8 day 11.
When readtable or textscan with datetime specification are used without a specific Format, they try to guess the format. If they see 11/08/2021 then they check all of the entries to see if the hypothesis of MM/dd/yyyy works. If it does not find any entries with leading number greater than 12, then it assumes that the initial number is month. If it finds leading values greater than 12 it proceeds to check the second pair to see if any of those are greater than 12; if not then it guesses dd/MM. If entries in the first and second both have values greater than 12 it will revert to the MM/dd guess.
In the case of this subset, all of the entries were 11/08 in the original file (before reading into the table) and so it found no evidence that MM/dd was wrong and stuck with that. If the range of dates on input had been a bit greater it would have automatically detected dd/MM.
Star Strider
on 10 Nov 2021
I agree that with respect to the inner workings of the code it’s not necessary for the formats to match, it is necessary for the format to match in order to hard-code (in this instance) the ‘start’ and ‘stop’ times . That the formats were ambiguous — with the resulting confusion — was the problem here. August is not November !
.
Walter Roberson
on 10 Nov 2021
Edited: Walter Roberson
on 10 Nov 2021
No, changing the Format of the start and last times here would not help.
You have three choices in this situation:
- Go back and fix the data source so it has the month and day the right way around, such as by using InputFormat at the time of readtable(); OR
- Code the start and last times deliberately wrong to match the data: start = datetime(2021,11,08,09,58,25); last = datetime(2021,11,08,10,01,00); OR
- Fix-up the data already read by switching day and month
To fix-up:
%gps datetime has reversed day and month
fmt = start.Format;
[year, mon, day] = ymd(gps.DateTime);
gps.DateTime = datetime(year, day, mon, 'Format', fmt) + timeofday(gps.DateTime);
Louise Wilson
on 10 Nov 2021
Wonderful thank you! Thank you for the explanation.
Walter Roberson
on 10 Nov 2021
Sorry, had a typo in my fix-up code.
Louise Wilson
on 10 Nov 2021
All good, it works perfectly :-) Thank you. The data I am working with is huge and a lot of time consuming processing has already been done so the fix up solution is preferrable by far!
Steven Lord
on 10 Nov 2021
If that doesn't work, perhaps the data in the file was more precise than you thought it was.
t1 = datetime(2021, 11, 10, 14, 25, 00)
t1 = datetime
10-Nov-2021 14:25:00
t2 = datetime(2021, 11, 10, 14, 25, 0.4)
t2 = datetime
10-Nov-2021 14:25:00
t1 >= t2 % correctly false even though they display the same
ans = logical
0
More Answers (0)
See Also
Categories
Find more on Data Preprocessing in Help Center and File Exchange
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!An Error Occurred
Unable to complete the action because of changes made to the page. Reload the page to see its updated state.
Select a Web Site
Choose a web site to get translated content where available and see local events and offers. Based on your location, we recommend that you select: .
You can also select a web site from the following list
How to Get Best Site Performance
Select the China site (in Chinese or English) for best site performance. Other MathWorks country sites are not optimized for visits from your location.
Americas
- América Latina (Español)
- Canada (English)
- United States (English)
Europe
- Belgium (English)
- Denmark (English)
- Deutschland (Deutsch)
- España (Español)
- Finland (English)
- France (Français)
- Ireland (English)
- Italia (Italiano)
- Luxembourg (English)
- Netherlands (English)
- Norway (English)
- Österreich (Deutsch)
- Portugal (English)
- Sweden (English)
- Switzerland
- United Kingdom(English)
Asia Pacific
- Australia (English)
- India (English)
- New Zealand (English)
- 中国
- 日本Japanese (日本語)
- 한국Korean (한국어)