datetime millisecond conversion puzzling

I have been having a puzzling issue with datetime conversion into milliseconds in R2017a.
startRecApp = datesConverted (recordingMatches(1)) +...
milliseconds(DifferencesInMilliseconds * 0.67);
endRecApp = datesConverted(recordingMatches(2)) -...
milliseconds(DifferencesInMilliseconds * 0.33);
z = (endRecApp - startRecApp);
z.Format = 'hh:mm:ss.SSS';
This snippet takes a datetime array (datesConverted) and checks for the difference (z) between the time the application stopped recording and the application started recording. This effectively returns a duration type of variable, which, in this case is 00:28:52.522.
If this is converted into milliseconds (i.e. milliseconds(z)), it returns
ans =
1732180
This is exactly what I needed, as another file, where the data are held, comes from the software with a 1,000 sampling rate (thus each line in the file (sample) represents one millisecond).
A bit later in the code, I have the following:
trigsStimulusStart = milliseconds (duration...
(datesConverted(stimulusOnsetMatches)...
- startRecApp, 'Format', 'hh:mm:ss.SSS'))
This takes the entire array of datesConverted (which are datetimes converted from a char array) and finds the indices corresponding to a stimulus presentation, attempting to return the milliseconds, thus the appropriate lines in the data file. Unlike the first example that returns an integer, this returns:
trigsStimulusStart =
1.0e+06 *
0.0256
0.0639
0.1079
0.1619
0.1977
0.2528
I do not understand this result at all. I am effectively doing the exact same thing, only in this case I subtract the startRecApp from an array, whereas the first example subtracts startRecApp from another variable (namely, endRecApp). How can I make this return integers, just like the "milliseconds(z)"?
Many thanks

댓글 수: 7

jonas
jonas 2018년 5월 28일
But those are milliseconds, no?
LM_BU
LM_BU 2018년 5월 28일
That's the point, I do not get why those are a bunch of doubles. They should be something like:
13345 62748 119756 654990, etc.
I am definitely missing something here, but not sure what that is.
jonas
jonas 2018년 5월 28일
From the doc:
MS = milliseconds(X)
If X is a duration array, then MS is a double array with each element equal to the number of milliseconds in the corresponding element of X. (emphasis mine)
I'm sorry if I am misunderstanding the question. What is the issue with the doubles?
LM_BU
LM_BU 2018년 5월 28일
Hi jonas,
Yes, I have noticed that. As I mentioned earlier, each line in the data file represents a millisecond. In this case, I am defining "epochs" (stimulusStart and stimulusEnd). These are exported in milliseconds (positive integers), which are then used as indices to the file's lines. For example, 32224 (stimulusStart) and 54112 (stimulusEnd) -> This is one epoch and it indicates that in line 32224 of the data file the stimulus appeared. I could not parse triggers directly into the software, so I am doing post-processing with datetimes.
Given the result I am receiving, Matlab obviously says that it requires integers as indices (newData.data(trigsStimulusStart, columnCount + 1) = 1;). This line implements a trigger identifier (with the ID "1") next to the correct file line.
I do not understand why the variable 'z' in the code returns what it returns, but trigsStimulusStart has a different format. This will help automate passing the proper file indices (lines, aka milliseconds) to another function for further analysis.
Thanks
jonas
jonas 2018년 5월 28일
편집: jonas 2018년 5월 28일
Thanks for elaborating, I understand the issue now. The only thing I can think of is that you cancel the decimals out in your first example when you take
(endRecApp - startRecApp)
These lines look suspicious
+milliseconds(DifferencesInMilliseconds * 0.67)
-milliseconds(DifferencesInMilliseconds * 0.33)
They could possibly sum to 1.0?
LM_BU
LM_BU 2018년 5월 28일
Hi jonas,
I am not sure if you've noticed, I used "fix()" and it returned the integers I was looking for. However, I inspected further what you've highlighted, and if I use round(DifferencesInMilliseconds * 0.67), it will return integers, exactly like what fix() did. As such, I will end up using round(), so many thanks for pointing me to the right direction!
Could you turn this into an answer, so that I can accept it?
jonas
jonas 2018년 5월 28일
I posted one for future reference, but you might aswell accept Rik's answer.
Glad it was resolved!

댓글을 달려면 로그인하십시오.

 채택된 답변

jonas
jonas 2018년 5월 28일

0 개 추천

Problem: why does milliseconds(X) sometimes return doubles?
Reason: Probably because the input value has decimals, in this case following these lines:
+milliseconds(DifferencesInMilliseconds * 0.67)
-milliseconds(DifferencesInMilliseconds * 0.33)
Fix? round() the output or the input to integers.

추가 답변 (1개)

Rik
Rik 2018년 5월 28일

1 개 추천

This actually may already return integers. If you look closely, you see the 1.0e+06* modifier.
trigsStimulusStart =
1.0e+06 *
0.0256
0.0639
0.1079
0.1619
0.1977
0.2528
This means that the first value is 25600 (or close to it), and the last value is 252800 (or close to it). You can change the output format if you like, but the values you have in your output seem already to be what you need.

댓글 수: 5

LM_BU
LM_BU 2018년 5월 28일
편집: LM_BU 2018년 5월 28일
Hi Rik,
Thank you! Yes, I have noticed that. However, I am trying to use trigsStimulusStart as indices for another array and of course MATLAB compiler complains: "Subscript indices must either be real positive integers or logicals."
If I had a result like the 'milliseconds(z)', this wouldn't be an issue. I am just wondering why the format is being changed and how to rectify it.
I suspect the format isn't changed. You can check with the code below if the output looks like integers. If they do, you can just round them to remove floating point rounding errors.
fprintf('%.2f\n',trigsStimulusStart)
Hi Rik,
This returns
25582.85
63945.85
107935.85
161911.85
197746.85
252817.85
...
Still, not sufficient to access indices. I have also tried converting the milliseconds to uint64, but I fear I might lose accuracy - how could I determine that?
Cheers
LM_BU
LM_BU 2018년 5월 28일
I have just tried fix(trigsStimulusStart) and it returns positive integers. Will need to investigate whether this is an appropriate solution and why this is needed here contrary to the variable 'z'.
Rik
Rik 2018년 5월 28일
The fix function rounds toward 0 (so it's equivalent to ceil for negative values, and floor for positive values). The code I gave you is not rounding, just displaying. I would suggest either round or ceil to round your values to integers. I can't explain why this output contains decimal values and your single case doesn't.

댓글을 달려면 로그인하십시오.

카테고리

도움말 센터File Exchange에서 Dates and Time에 대해 자세히 알아보기

질문:

2018년 5월 28일

댓글:

2018년 5월 28일

Community Treasure Hunt

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

Start Hunting!

Translated by