Datestr problem with Hour
現在この質問をフォロー中です
- フォローしているコンテンツ フィードに更新が表示されます。
- コミュニケーション基本設定に応じて電子メールを受け取ることができます。
エラーが発生しました
ページに変更が加えられたため、アクションを完了できません。ページを再度読み込み、更新された状態を確認してください。
古いコメントを表示
I wrote a test routine to set a start time stamp and step through hours.
function HourlyDateTEST2()
dvec(1)=2014;
dvec(2)=06;
dvec(3)=15;
dvec(4)=21;
dvec(5)=00;
dvec(6)=00;
dateVal=datenum(dvec);
for ii = 1:7
datestr(dateVal, 'mm/dd/yyyy HH:MM:SS')
dateVal = dateVal + 1/24;
end;
end
The output looks like the following:
06/15/2014 21:00:00
06/15/2014 22:00:00
06/15/2014 23:00:00
06/15/2014 00:00:00
06/16/2014 01:00:00
06/16/2014 02:00:00
06/16/2014 03:00:00
Notice that the 4th line has the wrong date. Should be 06/16/2014 00:00:00.
What am I doing wrong?
I am using MATLAB R2014a.
採用された回答
Star Strider
2014 年 6 月 15 日
13 件のコメント
Excepting for
>> addtodate(datenum(now),[1:7].','h')
Error using addtodate (line 49)
Quantity must be a numeric scalar.
>>
it would be. Don't know why it wasn't vectorized; seems easy enough to have been.
ADDENDUM
Actually, now I realize why...just played at adding a version for my R12 using datenum instead of the current mex file that does the guts and where one has a problem in a neat implementation is adding the vector to the right datevec column.
One can't write
v=datevec(dn); % the datevec from the input origin
v(idx)=v(idx)+addVal; % addVal is the dT to add for field idx
R=datenum(v); % if addVal is a vector as in my usage above
Can only write it as a whole vector
vadd=v(idx)+addVal;
and then pass the scalar values for the other fields explicitly. That means, as near as I can tell, having to use a CASE statement to explicitly write each possible field individually. Doable, but not neat; TMW chose to not...
Star Strider
2014 年 6 月 15 日
Definite needs vectorizing, since that behavior is still present in 2014a.
When I use it, it’s usually in a loop, which is actually not too much of a hindrance unless there are a lot of them. Using it in a loop does get around the floating-point-approximation problem, though.
I’ll submit vectorizing it as a ‘Support’ request. Nothing ventured, nothing gained. (My last brilliant idea was to add an engineering notation edit descriptor to the fprintf options. Maybe 1014b?)
dpb
2014 年 6 月 15 日
Well, there's always arrayfun and friends...
Harold Kidder
2014 年 6 月 16 日
My application requires a loop. I tried two approaches:
Approach 1 -- Offset from start date.
function HourlyDateTEST2()
dvec(1) = 2014;
dvec(2) = 06;
dvec(3) = 15;
dvec(4) = 21;
dvec(5) = 00;
dvec(6) = 00;
dateStart = datenum(dvec);
for ii = 0:6
dateVal = addtodate(dateStart, ii, 'hour');
datestr(dateVal, 'mm/dd/yyyy HH:MM:SS')
end;
end
Result:
06/15/2014 21:00:00
06/15/2014 22:00:00
06/15/2014 23:00:00
*06/16/2014 00:00:00*
06/16/2014 01:00:00
06/16/2014 02:00:00
06/16/2014 03:00:00
Approach 2 – Update dateVal on each loop
function HourlyDateTEST3()
dvec(1) = 2014;
dvec(2) = 06;
dvec(3) = 15;
dvec(4) = 21;
dvec(5) = 00;
dvec(6) = 00;
dateVal = datenum(dvec);
for ii = 0:6
datestr(dateVal, 'mm/dd/yyyy HH:MM:SS')
dateVal = addtodate(dateVal, 1, 'hour');
end;
end
Result:
06/15/2014 21:00:00
06/15/2014 22:00:00
06/15/2014 23:00:00
*06/15/2014 00:00:00*
06/16/2014 01:00:00
06/16/2014 02:00:00
06/16/2014 03:00:00
Approach 1 worked but Approach 2 gave the same result as using dateVal + 1/24. Must still be some round off error.
I'll use Approach 1.
dpb
2014 年 6 月 16 日
...My application requires a loop.
Why should that be, necessarily?
...
Approach 2 – Update dateVal on each loop...
Of course; it's the same thing as you did originally, just recast.
It's no different than running a for loop over a floating point iterator that ends up either one under or one over the expected number depending on which way the rounding goes on any particular numeric value.
Star Strider
2014 年 6 月 16 日
編集済み: Star Strider
2014 年 6 月 16 日
I’m glad you found a workable solution.
This is interesting. The date functions are usually robust. I submitted the results of your experiment (the URL of this thread) to MathWorks Support and reported it as a bug.
I also asked that any replies to me be copied to Harold Kidder and to dpb.
...date functions are usually robust
The symptoms are quite easy to generate if one uses floating point computations outside the internals of the functions as did OP in both of his cases that fail. It's unavoidable when the roundoff is accumulated externally as both of those cases do.
If, otoh, one starts w/ the base value and increments that value by the integer values, then the roundoff is limited and joy ensues.
It's why I've always preferred the vector solution as in original response; one avoids making the mistake by accident or forgetting.
Star Strider
2014 年 6 月 16 日
I could understand being off by a few seconds or even a minute as the result of floating-point approximation error, but having the time roll back to midnight of the same day, rather than advancing to midnight (or close to it) of the next day is clearly a bug!
The error will only be ~1E-15 or so on the datenum; since the day in the whole part, if truncate ( fix instead of round as example), the day would still be the preceding; only when the fractional part is 0+ instead of 9- will the whole portion have yet turned over. So, the datenum value isn't off by a whole day in absolute value, only that it hasn't yet turned over the new leaf.
I've mentioned earlier I've had cases where I could see the effects when using floating point outside the various functions and then utilizing those values inside. Your case here is the only time I've ever observed it within where up until now the rounding has never shown up in anything I've ever caught it at, anyway.
I was going to demonstrate the value difference but interestingly this morning I can't duplicate it...I just reran OPs test here and received--
>> for ii = 1:7
datestr(dateVal, 'mm/dd/yyyy HH:MM:SS')
dateVal = dateVal + 1/24;
end
ans =
06/15/2014 21:00:00
ans =
06/15/2014 22:00:00
ans =
06/15/2014 23:00:00
ans =
06/16/2014 00:00:00
...
Now that one I can't explain...that's Twilight Zone stuff, there.
ADDENDUM
Just for grins I closed and restarted Matlab and can't reproduce it there, either. Yet last night got the OPs results. Wishing now had save the intermediaries then but they were already in the bit bucket....
MOST peculiar...
Star Strider
2014 年 6 月 16 日
You obviously did that from the Command Window. I just now did the same thing in my test function (I clear and close all at the top) and the Command Window and repeated OP’s results in both.
Yes all I did up to now was at the command line. I also just put in a script and still can't reproduce it this AM.
If you can repeat it, save the datenum values and then run one of the integer-addition cases also saving the datenums there. Then do
diff(dnfloatcase,dnintegercase)
Star Strider
2014 年 6 月 16 日
I reported this a a bug to TMW yesterday. I got an e-mail a few minutes ago that said that they were able to reproduce it in R2014a, and will fix it ‘in a future release’. Whether this means an update or wait until R2014b I’m not sure. I sent them the link to this thread, so they have all the information they need.
Congratulations to Harold for discovering it!
dpb
2014 年 6 月 16 日
I'd still be curious if you can generate the two cases to see the actual datenum values. You running 32- or 64-bit version?
I'm still greatly puzzled how can't now seem to reproduce it here when was certain saw it in the original loop version. I suppose I could have mistakenly thought I saw what I didn't.
その他の回答 (1 件)
dpb
2014 年 6 月 15 日
What am I doing wrong?
for ii = 1:7
datestr(dateVal, 'mm/dd/yyyy HH:MM:SS')
dateVal = dateVal + 1/24;
...
Using floating point arithmetic; the rounding in the accumulation of the 1/24 factor caused it.
Use
>> datestr(datenum(dvec(1),dvec(2),dvec(3),dvec(4)+[0:7].',dvec(5),dvec(6)))
ans =
15-Jun-2014 21:00:00
15-Jun-2014 22:00:00
15-Jun-2014 23:00:00
16-Jun-2014 00:00:00
16-Jun-2014 01:00:00
16-Jun-2014 02:00:00
16-Jun-2014 03:00:00
16-Jun-2014 04:00:00
>>
instead (add the integer hours, not the fractional days) to avoid rounding errors.
カテゴリ
ヘルプ センター および File Exchange で Time Series Objects についてさらに検索
製品
参考
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!Web サイトの選択
Web サイトを選択すると、翻訳されたコンテンツにアクセスし、地域のイベントやサービスを確認できます。現在の位置情報に基づき、次のサイトの選択を推奨します:
また、以下のリストから Web サイトを選択することもできます。
最適なサイトパフォーマンスの取得方法
中国のサイト (中国語または英語) を選択することで、最適なサイトパフォーマンスが得られます。その他の国の MathWorks のサイトは、お客様の地域からのアクセスが最適化されていません。
南北アメリカ
- América Latina (Español)
- Canada (English)
- United States (English)
ヨーロッパ
- 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)
