C# と VB.NET の質問掲示板

ASP.NET、C++/CLI、Java 何でもどうぞ

C# と VB.NET の入門サイト

Re[3]: VB6とVB.NETのDateDiff関数の違いについて


(過去ログ 120 を表示中)

[トピック内 5 記事 (1 - 5 表示)]  << 0 >>

■70339 / inTopicNo.1)  VB6とVB.NETのDateDiff関数の違いについて
  
□投稿者/ ぽこぽこ (1回)-(2014/03/13(Thu) 11:56:42)

分類:[VB.NET/VB2005 以降] 

開発環境:Win7 32bit, VB.NET3.5

現在VB6で作成されたアプリをVB.NETでリプレスする作業をしております。
そのなかで、DateDiff関数を用いて日数の計算をしているロジックがあるのですが
VB6とVB.NETで挙動が異なっております

------------------------------------------------
【VB6】
DateDiff("d", Now, CDate("2014-03-15"))
> 2

【VB.NET】
DateDiff("d", Now, CDate("2014-03-15"))
> 1

DateDiff("d", CDate(Now.ToString("yyyy-MM-dd")), CDate("2014-03-15"))
> 2

※Nowの値は、2014-03-13 10:00が入るとする
------------------------------------------------

結果を見る限り、VB.NETになって時間基準(24時間にみたない場合切り捨て)に
なっているように思いますが、MSDNやWEB上で検索しても
DateDiffの仕様変更について記述されている所がありませんでした。
そこで以下のご質問をさせてください。

1.自分の調べ方が悪いだけかもしれませんが、
このDateDiffの挙動が変わった件について書かれている参考サイトやMSDNのページが
ありましたら教えていただきたいです。

2.VB.NETになって時間基準(24時間にみたない場合切り捨て)になったと勝手に自分の中で認識しておりますが
それが本当に正しいのでしょうか?

初歩的なご質問ですがよろしくお願いします。

引用返信 編集キー/
■70340 / inTopicNo.2)  Re[1]: VB6とVB.NETのDateDiff関数の違いについて
□投稿者/ shu (508回)-(2014/03/13(Thu) 12:37:56)
No70339 (ぽこぽこ さん) に返信

MSDNの内容で解説項目により、2つの日時の間にいくつの時間間隔が存在するかという値を返すので
時間が異なっていると(後ろの時間が前の時間より小さいと)日付だけで比べた場合より1少なくなりますね。
http://msdn.microsoft.com/ja-jp/library/b5xbyt6f(v=vs.90).aspx


> CDate(Now.ToString("yyyy-MM-dd"))
ですが Date.Todayとしたほうがよいです。


引用返信 編集キー/
■70343 / inTopicNo.3)  Re[2]: VB6とVB.NETのDateDiff関数の違いについて
□投稿者/ ぽこぽこ (3回)-(2014/03/13(Thu) 14:21:49)
回答有難うございます

> MSDNの内容で解説項目により、2つの日時の間にいくつの時間間隔が存在するかという値を返すので
> 時間が異なっていると(後ろの時間が前の時間より小さいと)日付だけで比べた場合より1少なくなりますね。
> http://msdn.microsoft.com/ja-jp/library/b5xbyt6f(v=vs.90).aspx

こちら参考にしていたのですが、見落としておりましたorz

VB6では時間の値は関係なく単純な日付の差分を返していて、VB.NETから時間間隔で返すように
変更された違いが記載されているサイト等があれば教えて頂きたかったです。
(終盤のフェーズで発覚したため、プログラム修正のための資料を作らないといけないので。。。)

>>CDate(Now.ToString("yyyy-MM-dd"))
> ですが Date.Todayとしたほうがよいです。
わざわざ有り難うございますm(__)m
修正時こちらを使用します!
引用返信 編集キー/
■70347 / inTopicNo.4)  Re[3]: VB6とVB.NETのDateDiff関数の違いについて
□投稿者/ 魔界の仮面弁士 (558回)-(2014/03/13(Thu) 23:30:40)
No70343 (ぽこぽこ さん) に返信
> >>CDate(Now.ToString("yyyy-MM-dd"))
>>ですが Date.Todayとしたほうがよいです。
> わざわざ有り難うございますm(__)m

あるいは、Now.Date のように、「Dateプロパティ」を使うという手法もあります。
Date プロパティは、Date型から時刻部を切り捨てて、日付だけを戻すプロパティです。


日付変数の部分をリテラル表記で記述するならば、
 x = DateDiff("d", #3/13/2014 10:00:00 AM#, #3/15/2014#)
ではなく、
 x = DateDiff("d", #3/13/2014 10:00:00 AM#.Date, #3/15/2014#.Date)
という処理にするイメージです。



その他、DateDiff 関数の代わりに下記のようにして計算することもできます。

 Function GetDays(ByVal dateFrom As Date, ByVal dateTo As Date) As Integer
  Return (dateTo.Date - dateFrom.Date).Days
 End Function

 Function GetTotalDays(ByVal dateFrom As Date, ByVal dateTo As Date) As Double
  Return (dateTo - dateFrom).TotalDays
 End Function



> 修正時こちらを使用します!

蛇足ですが、VB.NET における DateDiff の問題点は、時刻部の扱いだけでは無かったりします。

  a = DateDiff( "yyyy", #1/5/1989#, #1/8/1989#)
  b = DateDiff( "yyyy", #1/5/1989#, #1/8/1990#)

VBA/VB6 で上記を算出すると、a は「0」年、b は「1」年を返しますが、
VB.NET の場合は事情が異なります。VBA と同じ結果を返すこともある一方、
a が「-63」年、bが「-62」年として計算されてしまうこともありえるのです。


それは、Windows のコントロールパネル「地域設定」が、和暦モードに設定されていた場合です。

和暦モードの場合、上記計算は
 a = 「昭和64年1月5日」から「平成元年1月8日」までの年数 
 b = 「昭和64年1月5日」から「平成2年1月8日」までの年数
という意味で演算されることになります。

その結果、a = 2 - 64、b = 1 - 64 として処理されます。
("yyyy" を DateInterval.Year 指定に変更しても同様です)

もちろん、西暦モードであれば VBA と同じ結果を返しますが、
明らかに問題のある実装であると言えます。
(特に官公庁系や、保険業者系のユーザーでは、和暦設定にされている可能性が…)



また、日付がらみといえば、午前/午後の文字列書式にも問題があったりします。

VBA/VB6 の Format 関数においては、
 a = Format(dt, "AM/PM hh:mm")
 b = Format(dt, "A/P hh:mm")
のような記述があった場合、VB6/VBA では
 a は「AM 03:45」「PM 04:56」といった表記
 b は「A 03:45」「P 04:56」といった表記
で変換されます。


VB.NET では書式文字列が変更になった関係で、上記が
 a = Format(dt, "tt hh:mm")
 b = Format(dt, "t hh:mm")
に変更されるのですが、この結果はコントロールパネルの地域設定に依存して、
 a は「AM 03:45」「PM 04:56」といった表記
 b は「A 03:45」「P 04:56」といった表記
になる場合もあれば、
 a は「午前 03:45」「午後 04:56」といった表記
 b は「午 03:45」「午 04:56」といった表記
になる場合があります。しかも、日本語版 Windows の初期設定は後者です。

『午』では、何のことか分からないですよね…!
引用返信 編集キー/
■70348 / inTopicNo.5)  Re[3]: VB6とVB.NETのDateDiff関数の違いについて
□投稿者/ 魔界の仮面弁士 (559回)-(2014/03/14(Fri) 00:04:17)
No70343 (ぽこぽこ さん) に返信
> VB6では時間の値は関係なく単純な日付の差分を返していて、VB.NETから時間間隔で返すように
> 変更された違いが記載されているサイト等があれば教えて頂きたかったです。
> (終盤のフェーズで発覚したため、プログラム修正のための資料を作らないといけないので。。。)

私は見たことが無いですね…。

仮にそのようなサイトがあったとしても、それは公式のものではなく、個人 blog や
掲示板などといった、コミュニティベースの情報となる可能性が高そうです。私見ですが。

そもそもこれは意図的な仕様ではなく、VB ランタイムの不具合であろうと考えています。

その根拠は、時刻部を含んだ日付に対する DateDiff の実装に関して、
今回の件以外にも、カレンダー週("ww" あるいは WeekOfYear)のパターンに対する
下記のような問題が報告されているからです。


[Microsoft Connect - Wrong return value with DateAndTime.Diff]
https://connect.microsoft.com/VisualStudio/feedback/details/278501/


しかも、当時の開発チームからのコメントを見ると…(以下、超意訳)

2007年6月 Huy Nguyen
 『こいつは VB.NET ランタイムのバグだね 将来のバージョンで直すね』
 『現状の回避策として DateDiff に渡す前に時刻部を除去して対処してみてよ』

2007年12月 Jonathan
 『悪い 検討の結果直せないことになっちゃった』
 『とりあえず Huy 提案の回避策を使っておいてよ 不明点があれば僕にメールで聞いてくれ』
引用返信 編集キー/


トピック内ページ移動 / << 0 >>

このトピックに書きこむ

過去ログには書き込み不可

管理者用

- Child Tree -