[833] たまにはエクセルでも 投稿者:ぽう 投稿日:2001/10/24(Wed)
土日にやっていたのが DATEDIF の謎に迫る! ということで
"YD" と "MD" の仕様を調べていました。
もう何年も前に考えて、わからずじまいになっていました。
"MD" の方はこんな計算の結果と一致するようです。
Function DateDif_MD(Date1, Date2)
If Day(Date2) >= Day(Date1) Then
DateDif_MD = Day(Date2) - Day(Date1)
Else
DateDif_MD = Date2 - DateSerial(Year(Date2), Month(Date2) -
1, Day(Date1))
End If
End Function
"YD" がわかりません。閏年と、開始日と終了日の日(yyyy/m/d の d) の
大小関係が、ずれに影響しているようなのですが。
(1)日だけ独立して計算している部分がある
(2)他の日付関数を呼び出している部分がある
(3)その他
という可能性を考えています。
とりあえず DATEDIF(,"YD") の結果と一致するように場合分けをしていったら
長大なコードになってしまいました。
今回も迷宮入りか… 重要な話ではないですが。(^_^;)
[833へのレス]Re: たまにはエクセルでも 投稿者:SIMO 投稿日:2001/10/24(Wed)
皆さん、はじめまして。SIMOです。ここでは初めての発言です。
ぽうさん、先日はお世話になりました。
懐かしい話題に釣られて出てきました。
>>"YD" がわかりません。閏年と、開始日と終了日の日(yyyy/m/d の d)
>>の大小関係が、ずれに影響しているようなのですが。
お宝リストに載せてあるのを書いた時に、この二つを集中して調べました。
あの年のF1に行ったときに、名古屋のホテルで、リブレットとにらめっこ
していたのを思い出しました。
お宝リストには、(気が弱いもんで(^^;;)はっきり書けなかったのですが、
"YD"は、はっきりバグですね。付け焼き刃で処理したのが見え見えです。
[833へのレス]Re: たまにはエクセルでも 投稿者:ぽう 投稿日:2001/10/24(Thu)
SIMO さんへ
WORLD PC EXPO ではお世話になりました。
せっかく来ていただいたので、長大なコードというのをご紹介しますね。
眉間に皺の跡がしのばれる作品となっております。(^_^;)
Function DateDif_YD(Date1 As Date, Date2 As Date) As Long
Dim d2 As Date
Dim md1 As Long
Dim md2 As Long
Dim x As Long
md1 = Month(Date1) * 100 + Day(Date1)
md2 = Month(Date2) * 100 + Day(Date2)
If md1 <= md2 Then
d2 = DateSerial(Year(Date1), Month(Date2), Day(Date2))
Else
d2 = DateSerial(Year(Date1) + 1, Month(Date2), Day(Date2))
End If
If Day(Date1) > Day(d2) Then
If IsLeap(Date2) And (Month(Date2) >= 3) Then
x = x + 1
End If
If IsLeap(Date1) Then
If (Month(Date1) >= 3) Then
x = x + 1
End If
If (md1 > md2) Then
x = x - 1
End If
If IsLeap(Date2) And (Month(Date1) <= 2) And (Month(Date2)
<= 2) Then
x = x + 1
End If
If (Month(Date1) = 1) And (Month(Date2) = 2) Then
x = x - 1
End If
End If
If IsLeap(Date2) And (Month(Date2) >= 4) Then
x = x - 1
If IsLeap(Date1) And (Month(Date1) <= 2) Then
x = x + 1
End If
End If
If IsLeap(Date1) And (Not IsLeap(Date2)) Then
If (Month(Date1) <= 2) Then
x = x + 1
End If
If ((Month(Date2) = 3) Or (Month(Date2) = 1)) And (md1
<= md2) Then
x = x - 1
End If
End If
If IsLeap(d2) Then
If (Month(Date2) = 3) Then
x = x - 1
End If
If (Month(Date2) >= 4) And (md1 <= md2) Then
x = x - 1
End If
End If
End If
DateDif_YD = d2 - Date1 + x
End Function
Function IsLeap(Date1 As Date) As Boolean
IsLeap = Month(DateSerial(Year(Date1), 2, 29)) = 2
End Function
こんな複雑なことをやっているわけはないですね。
[833へのレス] Re: たまにはエクセルでも 投稿者:角田 投稿日:2001/10/25(Thu)
こんにちは。興味深い話題ですね。
[YD]の結果を眺めてたら面白い規則性があるようですね。
平年→閏年の場合に
2001/1/1 〜 2004/2/28 → 58
2004/2/29 → 59
2004/3/ 1 → 59
2004/3/ 2 → 60
となるんですが、この「58・59・59・60」という
パターンが終了日の2月末日位置固定ではなく、開始日の
「日」に合わせて、このパターンを維持したままシフトして
いくんですね。
[2001/1/2〜]にすると[2004/2/29,3/1,3/2,3/3]
[2001/1/3〜]にすると[2004/3/1,3/2,3/3,3/4]
[2001/1/4〜]にすると[2004/3/2,3/3,3/4,3/5]
ただし、開始日の「月」が変わると、また元の位置に戻って
2001/2/1 〜 2004/2/28 → 28
2004/2/29 → 29
2004/3/ 1 → 29
2004/3/ 2 → 30
2001/4/1 〜 2004/2/28 → 333
2004/2/29 → 334
2004/3/ 1 → 334
2004/3/ 2 → 335
からスタートしていきます(3月の場合には現れませんね)。
逆に閏年→平年だと
2000/1/1 〜 2005/2/28 → 58
2005/3/ 1 → 60
2005/3/ 2 → 61
2000/2/1 〜 2005/2/28 → 27
2005/3/ 1 → 29
2005/3/ 2 → 30
という風に[59・28が抜けた]パターンが同じ様にシフトして行きます
(こちらは3月以降は現れません)。
閏年→閏年や平年→平年では全く現れないですね。
『2月末日位置固定ではなく、開始日の「日」に合わせて、
このパターンを維持したままシフトしていく 』
というのがポイントじゃ〜ないかと見てますが‥‥‥
2001/1/2 〜 2004/2/28 → 57
2004/2/29 → 58
2004/3/ 1 → 58
2004/3/ 2 → 59
という風に「日数が減って、同じ日付位置(2/29,3/1)でダブる」
ならば単に月末処理の不具合だけでしょうけど、実際は
2001/1/2 〜 2004/2/29 → 58
2004/3/ 1 → 59
2004/3/ 2 → 59
2004/3/ 3 → 60
という風に「同じ日数位置でダブる」という事は『終了日』を
『開始日の日』だけ前シフトさせて『1日〜』という計算に換算
しているのではないか、とも考えられないでしょうか‥‥‥
[833へのレス] Re: たまにはエクセルでも 投稿者:ぽう 投稿日:2001/10/25(Thu)
角田 さんへ
>という風に「同じ日数位置でダブる」という事は『終了日』を
>『開始日の日』だけ前シフトさせて『1日〜』という計算に換算
>しているのではないか、とも考えられないでしょうか‥‥‥
ありがとうございます。(^_^)
そうか〜 開始日の日だけシフトして、それから差の計算ですね。
Function MyDateDifYD(Date1 As Date, Date2 As Date) As Long
Dim d1 As Date
Dim d2 As Date
d1 = Date1 - Day(Date1) + 1
d2 = Date2 - Day(Date1) + 1
If Month(d1) <= Month(d2) Then
MyDateDifYD = DateSerial(Year(d1), Month(d2), Day(d2)) - d1
Else
MyDateDifYD = DateSerial(Year(d1) + 1, Month(d2), Day(d2))
- d1
End If
End Function
2000年付近のデータで試してみましたが、結果は一致するようです。
もしもこの計算方法だとしたら、Month(d1) <= Month(d2) の比較のために
開始日を1日にしたのでしょうか… (^_^;)
SIMO さんへ
>涙無しには見れませんね、長大コード。(^^;;;
>プリントアウトして、じっくり見ているんですが、未だに何やってるのかよくわか
りません。
DATEDIF の結果と差が出たらそれを打ち消すためのコードを書き加えて
行っただけで、私にもどういう意味があるのかはわかっていません。(^_^;;
>R5Jでは、不具合はありませんでした。
ありがとうございます。そうですよね… 別段、難しい計算でもないですし、
普通に計算すればいいのに、本当にどうしてなんでしょうね >Excel