- PR -

仏暦環境での日付の扱いについて

投稿者投稿内容
Chikota
常連さん
会議室デビュー日: 2005/09/08
投稿数: 23
投稿日時: 2006-04-03 12:57
VB.NET2003、Access2000にてwindowsアプリケーションを作成しています。

PCの言語環境による日付の扱いで質問させていただきます。

windowsの日付表示設定で、西暦と仏暦を使用しているマシンがあります。
例えば、西暦で2006年は、仏暦で2549年になります。

2006年4月3日
西暦:4/3/2006
仏暦:4/3/2549

仏暦表示の環境で、DateTimePickerのValueフィールドにDataRowの日付フィールドにデータ連結をし、その値のアップデートの際、日付が正しく更新されません。
上記の日付をDateTimePicker(以下Dtpとします)で指定すると、
Dtp.Text = "4/3/2549"
Dtp.Value = #4/3/2006#
となります。
OLEDBCommandのParameterにDataRowの日付フィールドの値をセットして更新するのですが、更新された値が、仏暦での2006年(西暦で1463年)になってしまいます。

Dim cmd as new OLEDBCommand
cmd.Parameters.Add(New OleDbParameter("@adjustDate", OleDbType.DBDate, 0, "adjustDate"))
cmd.Parameters("@adjustDate").Value = dataRow("adjustDate")

ExecuteNonQueryをする直前のパラメータをイミディエイトウィンドウで確認したところ、

?cmd.Parameters("@adjustDate").Value
#4/3/2006# {Date}
[Date]: #4/3/2006#

の値が入っています。
また、この値をString表示すると

?cmd.Parameters("@adjustDate").Value.ToString
"3/4/2549 0:00:00"

となります。

ところが、ExecuteNonQueryを実行すると、実際にDBに格納されるのは4/3/1463(仏暦の4/3/2006)となってしまいます。

OLEDBCommandを使わずにDataAdapterを使用しても同様です。

Dateの値は仏暦や西暦を問わず共通の値だと認識していたのですが、日付表示環境が仏暦の場合は、DateValueに#3/4/2549#となるように設定しなくてはいけないのでしょうか。

どなたかアドバイスをいただけないでしょうか。
よろしくお願いいたします。
マー帽
常連さん
会議室デビュー日: 2006/01/31
投稿数: 21
投稿日時: 2006-04-05 10:19
こんにちは。
仏暦環境の事は知らないのですが、
ヒントになればと思い、書かせて頂きます。

#試してみようと思いましたが、設定方法が分かりませんでした。
#タイ語版のWindowsが必要なのでしょうか?

引用:

Shirathaiさんの書き込み (2006-04-03 12:57) より:
ExecuteNonQueryをする直前のパラメータをイミディエイトウィンドウで確認したところ、

?cmd.Parameters("@adjustDate").Value
#4/3/2006# {Date}
[Date]: #4/3/2006#

の値が入っています。
また、この値をString表示すると

?cmd.Parameters("@adjustDate").Value.ToString
"3/4/2549 0:00:00"

となります。


ここまでのVB.NETの動作は正しいと思います。
実際の日付は西暦2006年であり、
表示する場合には仏暦2549年と表示されているのでしょう。

引用:

ところが、ExecuteNonQueryを実行すると、実際にDBに格納されるのは4/3/1463(仏暦の4/3/2006)となってしまいます。



この部分はACCESSでの更新だと思いますが、
ACCESS自身も仏暦環境で動作しているために
仏暦の日付を受け取り、西暦のデータに変換して
書き込んでいるのではないでしょうか?

そうであれぱ、VB.NETから仏暦の日付を
渡す必要があるように思われます。

以上、参考になりましたら幸いです。
じゃんぬねっと
ぬし
会議室デビュー日: 2004/12/22
投稿数: 7811
お住まい・勤務地: 愛知県名古屋市
投稿日時: 2006-04-05 10:34
引用:

Shirathaiさんの書き込み (2006-04-03 12:57) より:

OLEDBCommandのParameterにDataRowの日付フィールドの値をセットして更新するのですが、更新された値が、仏暦での2006年(西暦で1463年)になってしまいます。


誤解があるかと思います。

"仏暦での" ではなく西暦の 2006 年として正しく更新されているでしょう。
これは、正しい動作で読み込み時に仏暦になるように変換するだけで済む話です。

実際の値と、見た目の値は別物だとお考えください。
DateTime 型が内部的にはどういう値の持ち方をしているのか、これを意識してみてください。

_________________
C# と VB.NET の入門サイト
じゃんぬねっと日誌
マー帽
常連さん
会議室デビュー日: 2006/01/31
投稿数: 21
投稿日時: 2006-04-05 11:07
引用:

Shirathaiさんの書き込み (2006-04-03 12:57) より:
ところが、ExecuteNonQueryを実行すると、実際にDBに格納されるのは4/3/1463(仏暦の4/3/2006)となってしまいます。



これは間違いなく4/3/1463と保存されているのですよね?

一度仏暦2551年2月29日でテストしてみてはいかがでしょうか?
もしACCESS側でも仏暦→西暦の変換が行われていれば
エラーになり更新できないと思います。
Chikota
常連さん
会議室デビュー日: 2005/09/08
投稿数: 23
投稿日時: 2006-04-05 13:01
返答が遅くなってしまい、申し訳ありません。

いただいたアドバイスの確認と、Dateパラメータによる動作を確認しました。


引用:
#試してみようと思いましたが、設定方法が分かりませんでした。
#タイ語版のWindowsが必要なのでしょうか?


仏暦表示への変更方法(Win2000)ですが、コントロールパネルの「地域のオプション」で「現在のユーザー設定」のロケールを「タイ語」にします。
日付のタブを表示すると、仏暦に変わっているのが確認できます。
タイ語のwindowsは必要ありませんが、windowsのCDを要求されるかもしれません。


引用:
"仏暦での" ではなく西暦の 2006 年として正しく更新されているでしょう。
これは、正しい動作で読み込み時に仏暦になるように変換するだけで済む話です。


間違いなく4/3/1463(西暦)で更新されているのか、についてですが、更新されています。
Accessを確認すると、他の日付はすべて4/3/2549と表示されている中、今回更新したレコードのみ4/3/2006と表示されており、windowsの設定を日本語や英語に戻して表示すると4/3/1943と表示されます。
また、更新後にこのデータをイミディエイトで確認すると#4/3/1463#となっています。


引用:
そうであれぱ、VB.NETから仏暦の日付を
渡す必要があるように思われます。


更新前にパラメータの値を#4/3/2549#に変更したところ、西暦2006年となりました。
コード:
cmd.Parameters("@adjustDate").Value=#4/3/2549#


ですが、西暦や仏暦などの「見た目」ではなく「値」自体を変更することになるので腑に落ちないものがあります。


引用:
一度仏暦2551年2月29日でテストしてみてはいかがでしょうか?


仏暦2/29/2551での更新はエラーとなりました。
エラーメッセージ:「抽出条件で型が一致しません。」


パラメータのタイプをDBDateからDateに変更したところ、もともと想定していた動作をしました。
コード:
cmd.Parameters.Add(New OleDbParameter("@adjustDate", OleDbType.Date, 0, "adjustDate")) 
cmd.Parameters("@adjustDate").Value = #4/3/2006#


上記のコードで西暦2006年、仏暦2549年がAccessに更新されました。

ですが、これだとTimeも一緒に格納されてしまうので、DataCommandで更新する場合にはDateTime.DateでTimeをカットできますが、DateTimePickerにデータバインドし、DataAdapterから更新するという場合に不要なTimeまで入ってしまって都合が悪いですよね。

とりあえず今回は、パラメータタイプをDateに変更することで対応することにして、パラメータタイプのDBDateとDateの違いについて調べてみようと思います。

いろいろとアドバイスいただき、大変ありがとうございました。
マー帽
常連さん
会議室デビュー日: 2006/01/31
投稿数: 21
投稿日時: 2006-04-05 16:52
少し補足です。

引用:

Shirathaiさんの書き込み (2006-04-05 13:01) より:
引用:
そうであれぱ、VB.NETから仏暦の日付を
渡す必要があるように思われます。


更新前にパラメータの値を#4/3/2549#に変更したところ、西暦2006年となりました。
コード:
cmd.Parameters("@adjustDate").Value=#4/3/2549#


ですが、西暦や仏暦などの「見た目」ではなく「値」自体を変更することになるので腑に落ちないものがあります。


この場合、型がそのままで値のみ変更すると
うるう年の処理でエラーとなるでしょうから、
他のタイプ、例えば文字タイプで渡す必要があると思います。

年の頭にGやBの文字を使用すれば仏暦,西暦も指定できるようです。
ACCESSのHelpで「仏暦」で検索するとヒットしました。
→「複数のカレンダー データベースの日付を指定する」


#ちなみに、不思議な事にこのPCでは「タイ語」がリストアップされません...
Chikota
常連さん
会議室デビュー日: 2005/09/08
投稿数: 23
投稿日時: 2006-04-05 21:11
引用:
この場合、型がそのままで値のみ変更すると
うるう年の処理でエラーとなるでしょうから、
他のタイプ、例えば文字タイプで渡す必要があると思います。


確かにおっしゃる通りでうるう年でエラーになってしまいます。

パラメータに文字タイプで渡す方法で手当たり次第に下記を試しましたが、いずれもうまくいきません。

・#4/3/1463#(西暦1463年、仏暦2006年)として更新される
 "4/3/2549"

・うるう年の場合、無効なDateTimeとして更新時にエラー
  "4/3/3092"(仏暦のYearにさらに差分の543年をプラス)

・無効な値としてパラメータに値セット時にエラー
 #4/3/g2006#、#4/3/g06#、#4/3/b2549#、#4/3/b2549#

・無効なDateTimeとして更新時にエラー
 "4/3/g2006"、"4/3/g06"、"4/3/b2549"、"4/3/b49"
 "#4/3/g2006#"、"#4/3/g06#"、"#4/3/b2549#"、"#4/3/b49#"


引用:
http://msdn2.microsoft.com/ja-JP/library/system.data.oledb.oledbtype(VS.80).aspx
Date 倍精度浮動小数点数として格納される日付データ (DBTYPE_DATE)。正数部は 1899 年 12 月 30 日以降の日数、小数部は 1 日の端数を示します。DateTime に割り当てられます。
DBDate yyyymmdd 書式の日付データ (DBTYPE_DBDATE)。DateTime に割り当てられます。


「書式の日付データ」というのが関係していそうですね。

パラメータタイプはDateにして、DateTimePickerへのデータバインドはせずにコード上でTimeを切った値をセットしてやる、というのが妥当なところなのでしょうか。
Jitta
ぬし
会議室デビュー日: 2002/07/05
投稿数: 6267
お住まい・勤務地: 兵庫県・海手
投稿日時: 2006-04-05 21:33
 「仏暦って何?フランス(仏蘭西)は西暦じゃないの?」とか、思ってしまった

> 実際にDBに格納されるのは4/3/1463(仏暦の4/3/2006)となってしまいます。
この、確認方法が問題ですかね。

 それと、データベース側が、何を求めているか。
 Date そのものの値と ToString を通した値を比べると異なっていることから、同じ値の見せ方を変えているということがわかると思います。見た目でわかりやすく書けば、「123」という「アラビア数字」を求めているか、「一二三」という漢数字を求めているか。
 データベースが、「一二三」という漢数字も「数字」として認識できるなら、「123」という値に変換して格納できるでしょう。しかし、アラビア数字しか「数字」として認識できないなら、プログラム側でアラビア数字に変換して、渡してやらなければなりません。

 逆に、取り出すときにアラビア数字としてしか取り出せないのか、漢数字としても取り出せるのか、その辺が問題になりますよね。


 う〜ん、仏暦には対応しているのに、皇紀には対応していないのか。。。(誰が使うんだよ)

スキルアップ/キャリアアップ(JOB@IT)