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

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

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

Re[5]: Windowsの設定で曜日が変わる


(過去ログ 148 を表示中)

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

■86564 / inTopicNo.1)  Windowsの設定で曜日が変わる
  
□投稿者/ 大阪 (1回)-(2018/02/15(Thu) 15:58:08)

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

環境:Windows7(64bit),VB2010,WinFormアプリ

文字列=>Date(又はDateTime)=>文字列(曜日表示)の変換を行いたいです。
変換元の文字列はJpegファイルのExif情報から取得したものです。

Windowsの日付と時刻の設定でカレンダーを和暦に設定した時
↓の(2)の方法では金曜日となってしまいます。(西暦の場合はOK)
又(1)の方法でDateオブジェクトを作成した場合はOKです。

文字列を加工して(1)の方法でDateオブジェクトを作成すればいけると思いますが、
カルチャを指定する等、他の方法はないでしょうか?

2/10は土曜日なのでOSのカレンダーの設定に左右されずに土曜日と表示させたいです。


Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
        'Dateオブジェクトの作成
        Dim date0 As Date = New Date(2018, 2, 10, 9, 52, 49) '(1)
        Dim date1 As Date = Date.Parse("2018/2/10 9:52:49") '(2)

        'カルチャを指定しない(現在のカルチャに依存)で文字列化 
        Dim str0 As String = date0.ToString("yyyy/MM/dd(ddd)")
        Dim str1 As String = date1.ToString("yyyy/MM/dd(ddd)")

        '表示 
        MsgBox(str0) 'OK
        MsgBox(str1) 'NG 日付と時刻の設定で和暦の場合、金曜日になってしまう
End Sub

引用返信 編集キー/
■86565 / inTopicNo.2)  Re[1]: Windowsの設定で曜日が変わる
□投稿者/ 魔界の仮面弁士 (1565回)-(2018/02/15(Thu) 16:46:43)
No86564 (大阪 さん) に返信
> 変換元の文字列はJpegファイルのExif情報から取得したものです。
どの EXIF タグのことか分かりませんが、元が Jpeg であれば、
 0x0132 ModifyDate
 0x9003 DateTimeOriginal
 0x9004 CreateDate
などのデータではありませんか?

もしそうならば、変換元の文字列は
"2018/2/10 9:52:49" 形式ではなく
"2018:02:10 09:52:49" 形式だと思うのですが。



> Windowsの日付と時刻の設定でカレンダーを和暦に設定した時
> ↓の(2)の方法では金曜日となってしまいます。(西暦の場合はOK)

西暦4006年(平成2018年)2月10日は 金曜日であっていますよ。
date1.Year は 4006 を返しますよね。


> カルチャを指定する等、他の方法はないでしょうか?
カルチャと書式の両方を指定してください。お奨めは Date.TryParseExact メソッドです。

日付として正しくない文字列が渡される可能性が無い場合には、
Date.TryParseExact ではなく Date.ParseExact でも構いません。
この場合はたとえば、
 date1 = Date.ParseExact("2018/2/10 9:52:49", "yyyy\/M\/d H\:mm\:ss", CultureInfo.InvariantCulture)
とか
 date1 = Date.ParseExact("2018:02:10 09:52:49", "yyyy\:MM\:dd HH\:mm\:ss", CultureInfo.InvariantCulture)
といった具合になります。


今回は日付でしたが、数値においても同様のカルチャ依存の問題がありますので、
文字列解析を行う場合にはご注意ください。
引用返信 編集キー/
■86566 / inTopicNo.3)  Re[2]: Windowsの設定で曜日が変わる
□投稿者/ 大阪 (2回)-(2018/02/15(Thu) 21:11:49)
No86565 (魔界の仮面弁士 さん) に返信

返信ありがとうございます。

> どの EXIF タグのことか分かりませんが、元が Jpeg であれば、
> "2018:02:10 09:52:49" 形式だと思うのですが。
予想通り、つっこまれました。掲示板でのやりとりでは"2018/2/10 9:52:49"の方が
日付として解りやすいと思い、あえてそのようにしましたが
実際は、仰せの通り"2018:02:10 09:52:49" 形式です。


> 西暦4006年(平成2018年)2月10日は 金曜日であっていますよ。
> date1.Year は 4006 を返しますよね。
そういう事だったんですね。理解しました。


> カルチャと書式の両方を指定してください。お奨めは Date.TryParseExact メソッドです。
> date1 = Date.ParseExact("2018/2/10 9:52:49", "yyyy\/M\/d H\:mm\:ss", CultureInfo.InvariantCulture)
提示の方法で期待通りの結果が得られました。
日時書式指定文字列でエスケープ文字の使用例を初めて見ました。
\なしでも結果に影響はないようですが
https://msdn.microsoft.com/ja-jp/library/8kb3ddd4(v=vs.110).aspx
によるとカスタム書式指定子として解釈されるリテラル文字の場合は
エスケープする方が良いみたいですね。
特定のカルチャに依存しない場合のCultureInfo.InvariantCultureも初めて知りました。
どうもありがとうございます。

> 今回は日付でしたが、数値においても同様のカルチャ依存の問題がありますので、
> 文字列解析を行う場合にはご注意ください。
これについても知識に乏しいのですが、非英語圏での小数点が「.」ではなく「,」であるといった事でしょうか?本題とは外れますが、後学の為、よろしければ教えてください。
引用返信 編集キー/
■86567 / inTopicNo.4)  Re[3]: Windowsの設定で曜日が変わる
□投稿者/ 魔界の仮面弁士 (1566回)-(2018/02/15(Thu) 22:40:05)
No86566 (大阪 さん) に返信
> 掲示板でのやりとりでは"2018/2/10 9:52:49"の方が

せめて "2018/02/10 09:52:49" ならばスルーしていたのですが。(^^;


> 日時書式指定文字列でエスケープ文字の使用例を初めて見ました。
> \なしでも結果に影響はないようですが

「/」はカルチャの影響を受けて、他の文字に書き変わるからです。

OS の地域設定に頼らず、アプリケーション側で CultureInfo を明示すれば
結果的にエスケープが不要になる可能性はありますけれどね。


実験として、コントロールパネルの地域設定で、日付の短い形式を
"yyyy/MM/dd" から "yyyy-MM-dd" に変更してみてください。


たとえば下記の場合
 s1 = "2018-02-15"
 s2 = "2018/02/15"
という違いが生じることになります。

'VB.NET
s1 = DateTime.Today.ToString("yyyy/MM/dd") 
s2 = DateTime.Today.ToString("yyyy\/MM\/dd")

'VBA
s1 = Format(Now, "YYYY/MM/dd")
s2 = Format(Now, "YYYY\/MM\/dd")


>> 今回は日付でしたが、数値においても同様のカルチャ依存の問題がありますので、
>> 文字列解析を行う場合にはご注意ください。
> 非英語圏での小数点が「.」ではなく「,」であるといった事でしょうか?

小数点記号もその一つです。
他には、通貨記号、負数表現、桁区切りの位置と記号、既定の小数桁数あたり。


Dim dec As Decimal = -12345678.901D

s = dec.ToString("C", New CultureInfo("ja-JP")) '「-\1,234,568」日本
s = dec.ToString("C", New CultureInfo("en-US")) '「($1,234,567.89)」米国
s = dec.ToString("C", New CultureInfo("en-GB")) '「-£1,234,567.89」英国 / 実際の£は半角

s = dec.ToString("N", New CultureInfo("ar-EG")) '「12,345,678.901-」アラビア語 (エジプト)
s = dec.ToString("N", New CultureInfo("de-CH")) '「-12'345'678.90」ドイツ語 (スイス)
s = dec.ToString("N", New CultureInfo("en-IN")) '「-1,23,45,678.90」英語 (インド)
s = dec.ToString("N", New CultureInfo("es-ES")) '「-12.345.678,90」スペイン語 (スペイン)
s = dec.ToString("N", New CultureInfo("es-US")) '「-12345,678.90」スペイン語 (米国)
引用返信 編集キー/
■86568 / inTopicNo.5)  Re[4]: Windowsの設定で曜日が変わる
□投稿者/ ぽぴ王子 (53回)-(2018/02/16(Fri) 09:25:16)
ぽぴ王子 さんの Web サイト
回答を書いているうちに弁士さんに先を越された上に正確な回答だったので
僕はそっと書きかけの内容を消してしまったわけですが。

以下、回答ではありません。ただ、特に苦言とかではないです。

> もしそうならば、変換元の文字列は
> "2018/2/10 9:52:49" 形式ではなく
> "2018:02:10 09:52:49" 形式だと思うのですが。

> 予想通り、つっこまれました。掲示板でのやりとりでは"2018/2/10 9:52:49"の方が
> 日付として解りやすいと思い、あえてそのようにしましたが
> 実際は、仰せの通り"2018:02:10 09:52:49" 形式です。

質問される方で、よく「〜〜というエラーが出ました」と発生した例外をうろおぼえで
書き写して質問をしている方がいらっしゃるのですが、そのたびに「正確な例外内容を
コピペしてください」と言われたりしてるんですよね。
なぜかというと、正確な例外の内容がわかればある程度どういった状況で例外が発生した
のかわかる 「かも」 しれないという話で、逆にあいまいな内容ではせっかく回答が
もらえるかもしれないチャンスをふいにしていることになります。
(どういった例外が出たのかは、正確には質問者の方しかわからないので)

今回のやりとりも似ているなと思ったのですが「日付として解りやすいと思い」という
気持ちで「2018:02:10 09:52:40」となっていた文字列を「2018/2/10 9:52:49」にして
しまうと、それはまったくの別のものになってしまいますし、もしかするとトンチンカン
な回答が返ってくる可能性もありました。
今回はたまたまExif情報から取得したという情報があったのと、魔界の仮面弁士さんが
その情報から正しい(と思われる)文字列フォーマットを提示してくださったので早期
解決できましたが、そうでなければなかなか解決できなかったかもしれません。

なにが言いたいのかというと「正しい回答を得るためには、正しい情報を提示してほしい」
ということです。

掲示板で自分が質問したスレッド以外のスレッドを見る方はあまりいないかもしれませんが
(回答者は除く)読まれた方はちょっと気に留めておいていただけると助かります。
引用返信 編集キー/
■86571 / inTopicNo.6)  Re[4]: Windowsの設定で曜日が変わる
□投稿者/ 大阪 (3回)-(2018/02/16(Fri) 10:09:24)
No86567 (魔界の仮面弁士 さん) に返信
返信ありがとうございます。

> 「/」はカルチャの影響を受けて、他の文字に書き変わるからです。
> 実験として、コントロールパネルの地域設定で、日付の短い形式を
> "yyyy/MM/dd" から "yyyy-MM-dd" に変更してみてください。
VB,VBA両方共、実験してみました。
仰せの通り、エスケープ文字の有無で結果に違いが出る事を確認しました。
今後、指定した形式で文字列として出力したい場合、エスケープ文字を付与するようにします。

> 小数点記号もその一つです。
> 他には、通貨記号、負数表現、桁区切りの位置と記号、既定の小数桁数あたり。
こちらについてもサンプルを確認しました。
今後、このような事案に遭遇した場合に備えさせていただきます。

非常に丁寧な回答を頂き、感謝いたします。
どうもありがとうございました。

解決済み
引用返信 編集キー/
■86572 / inTopicNo.7)  Re[5]: Windowsの設定で曜日が変わる
□投稿者/ 大阪 (4回)-(2018/02/16(Fri) 10:10:54)
No86568 (ぽぴ王子 さん) に返信
返信ありがとうございます。

ご指摘、ありがとうございます。
以後、注意いたします。
解決済み
引用返信 編集キー/
■86574 / inTopicNo.8)  Re[4]: Windowsの設定で曜日が変わる
□投稿者/ 魔界の仮面弁士 (1567回)-(2018/02/16(Fri) 10:26:30)
CurrentCulture のことを書き漏らしていたので追記。
# 解決済みマークがついた後ではありますが。

No86567 (魔界の仮面弁士) に追記
>>> 実際は、仰せの通り"2018:02:10 09:52:49" 形式です。

CurrentCulture を通じてアプリケーションのカルチャを変更すれば、
EXIF タグ形式の日付文字列を、CDate で読み取ることも可能です。

 Dim cul As New CultureInfo("ja-JP")
 cul.DateTimeFormat.DateSeparator = ":"
 Application.CurrentCulture = CultureInfo.ReadOnly(cul)

 Dim dt1 = CDate("2018:02:10 09:52:49")
 Dim dt2 = Date.Parse("2018:02:10 09:52:49")


あるいは、コントロールパネルの設定で、
日付の区切り記号と時刻の区切り記号の両方を
「:」に変更しておいても、"2018:02:10 09:52:49" を読み取れます。


カルチャーの変更のためには
 System.Globalization.CultureInfo.CurrentCulture
 System.Globalization.CultureInfo.CurrentUICulture
 System.Threading.Thread.CurrentThread.CurrentCulture
 System.Threading.Thread.CurrentThread.CurrentUICulture
などが使えます。
http://smdn.jp/programming/netfx/locale/0_abstract/

同様の機能として、VB 限定ではありますが
 My.Application.ChangeCulture
 My.Application.ChangeUICulture
も用意されています。こちらは DateSeparator は指定できませんけれどね。


…とはいえ、EXIF タグの解析に関しては、やはり、
TryParseExact / ParseExact メソッドを使うのが良いでしょう。
 .DateTimeFormat.DateSeparator = ":"
は一般ユーザーが使うような書式ではありませんので、
流石にこれを CurrentCulture に割り当てるのはお奨めしません。
解決済み
引用返信 編集キー/
■86575 / inTopicNo.9)  Re[5]: Windowsの設定で曜日が変わる
□投稿者/ 大阪 (5回)-(2018/02/16(Fri) 11:14:15)
No86574 (魔界の仮面弁士 さん) に返信
追加情報、ありがとうございます。
実装は、例外を考慮してTryParseExactを使います。
解決済み
引用返信 編集キー/


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

このトピックに書きこむ

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

管理者用

- Child Tree -