Visual Basic 中学校 掲示板
投稿内容
タグのない投稿を抽出
統計
RSS
Visual Basic 中学校
>
投稿一覧
>
日付の書式について
Culture
日付
タグの編集...
投稿者
Coleman
 (社会人)   投稿日時
2020/10/5 12:09:52
使用言語:VB2013(.net framework 4.5)
こんにちは。
WinFormアプリを作成していますが、処理したテキストデータを保存する時に、
例えば2020年10月5日の場合、"20201005.txt"のようにしています。
この文字列は、「Today.ToString("yyyyMMdd") & ".txt"」のようにしていますが、
一部の人では、例えば2020年10月5日だと"321005.txt"のように、
年を表す"yyyy"の部分が和暦になっています。
(おそらく、frameworkが古いため、令和2年が平成32年と認識されているものと推測します。)
令和・平成の問題はさて置き、以下の質問があります。
1.書式"yyyy"に和暦が適用されてしまうのは、Windows側の設定等が
関係しているのでしょうか?
2.いかなる場合でも、書式"yyyy"に西暦4桁を適用するには、
VB側でどのようにすればいいでしょうか?
よろしくお願いします。
投稿者
魔界の仮面弁士
 (社会人)   投稿日時
2020/10/5 12:53:56
> 1.書式"yyyy"に和暦が適用されてしまうのは、Windows側の設定等が
> 関係しているのでしょうか?
Windows の地域設定です。
たとえば Today.ToString("MM/dd") が "10-05" になる可能性もありますし、
1234.ToString("#,##0") が "1.234" になる可能性もあります。
> 2.いかなる場合でも、書式"yyyy"に西暦4桁を適用するには、
> VB側でどのようにすればいいでしょうか?
ToString メソッドや String.Format メソッドの引数に、
CultureInfo クラスのインスタンスを渡します。
たとえば CultureInfo.InvariantCulture など。
https://qiita.com/tomboyboy/items/daf0d8427ba392c11a53
あるいは My.Application.ChangeCulture を使う手も。
投稿者
Coleman
 (社会人)   投稿日時
2020/10/5 13:20:59
魔界の仮面弁士さま、ご丁寧にご説明頂きありがとうございました。
CultureInfoを引数に渡す方法は知らなかったので、勉強になりました。
あと、My.Application.ChangeCultureだと一度に全体の対応ができそうなので、こちらを試してみようと思います。
これは引数の型がStringですが、CultureInfo.InvariantCultureに相当するカルチャを設定するには
My.Application.ChangeCulture("")でよいのでしょうか?
※以下「ApplicationBase.ChangeCulture(String) メソッド」を参照しました。
https://docs.microsoft.com/ja-jp/dotnet/api/microsoft.visualbasic.applicationservices.applicationbase.changeculture?view=netframework-4.8
投稿者
Coleman
 (社会人)   投稿日時
2020/10/19 17:51:29
とりあえず、My.Application.ChangeCulture("")を行うことで、
日付のToString("yyyyMMdd") は、西暦年4桁+月2桁+日2桁(月と日は左側0埋め)になったようですが、
これとは別に、例えば、Decimal変数dec1に対して
dec1 = "10.2"
のように全角数字文字列を与えると例外が発生します。
この例外はSystem.InvalidCastExceptionで、要はDecimalに変換できない、ということで、
本来ならば半角数字にしたものをDecimalにキャストすべきところを
それを忘れていた所を発見できて、これはこれで良かったのですが、
その他、My.Application.ChangeCulture("")を行うことで、
どのような影響が出てくるでしょうか?
投稿者
魔界の仮面弁士
 (社会人)   投稿日時
2020/10/19 19:45:43
My.Application.ChangeCulture() には、"ja" や "ja-JP" などのカルチャ名を渡します。
"" を渡すと、ニュートラルカルチャ(米語相当)となります。
ただし My.Application.ChangeCulture では、日付設定の
「西暦 (日本語)」「西暦 (英語)」「和暦」といった細かい設定が行えません。
カレンダーまで指定する場合は、System.Globalization.CultureInfo.CurrentCulture を
差し替える方法を使います。
これは、CultureInfo の DateTimeFormat.Calendar を切り替えることで対応できます。
Private
jp
As
New
System.Globalization.CultureInfo(
"ja-JP"
)
'日本のカルチャ
Private
Sub
Form1_Load(sender
As
Object
, e
As
EventArgs)
Handles
MyBase
.Load
Dim
dic
As
New
Dictionary(
Of
String
, System.Globalization.Calendar)()
Dim
dfi =
DirectCast
(jp.DateTimeFormat.Clone(), System.Globalization.DateTimeFormatInfo)
For
Each
cal
In
jp.OptionalCalendars
'日本のカルチャで使用可能なカレンダーを列挙
dfi.Calendar = cal
dic.Add(dfi.NativeCalendarName, cal)
Debug.WriteLine(cal.
GetType
().FullName)
Next
ComboBox1.DisplayMember =
"Key"
ComboBox1.ValueMember =
"Value"
ComboBox1.DataSource = dic.ToArray()
'使用可能なカレンダーを ComboBox に列挙してみます
End
Sub
Private
Sub
ComboBox1_SelectedIndexChanged(sender
As
Object
, e
As
EventArgs)
Handles
ComboBox1.SelectedIndexChanged
' カレンダーを変更してみてみます
Dim
cal =
TryCast
(ComboBox1.SelectedValue, System.Globalization.Calendar)
If
cal
Is
Nothing
Then
TextBox1.Text =
""
TextBox2.Text =
""
Else
jp.DateTimeFormat.Calendar = cal
System.Globalization.CultureInfo.CurrentCulture = jp
TextBox1.Text = Now.ToString(
"G"
)
' CurrentCulture を差し替えるのではなく、Format あるいは ToString 時に
' カルチャを指定する方法もあります。この方法だと、現在のカルチャに依存せずに
' 書式を切り替えられますので、たとえば「令和2年(2020年)」などのような
' 複数カルチャの文字列を扱う際にも応用できます。
TextBox2.Text =
String
.Format(jp,
"{0:ggg yyyy/MM/dd HH:mm:ss.fffffff}"
, Now)
End
If
End
Sub
投稿者
魔界の仮面弁士
 (社会人)   投稿日時
2020/10/19 20:15:05
> その他、My.Application.ChangeCulture("")を行うことで、
> どのような影響が出てくるでしょうか?
たとえば、日付書式なら、gg や MMMM や t などに影響を与えます。
数値書式なら、Double.PositiveInfinity.ToString() なども変わりますね。
> dec1 = "10.2"
> のように全角数字文字列を与えると例外が発生します。
これを許可したいなら、 "ja-JP" のカルチャのままにした方が良いでしょう。
String.Format や ToString や TryParse の際にカルチャを明示することで、
文字列への/文字列からの変換を現在のカルチャに依存させることなく
開発者が定めた特定のカルチャに基づいて行わせることができます。
TextBox1.Text =
String
.Format(CultureInfo.InvariantCulture,
"{0:ggg yyyy/MM/dd HH:mm:ss.fffffff}"
, Now)
なお、使用可能なカルチャの一覧は、CultureInfo.GetCultures メソッドで得られます。
Private
Sub
Form1_Load(sender
As
Object
, e
As
EventArgs)
Handles
MyBase
.Load
ComboBox1.DataSource = System.Globalization.CultureInfo.GetCultures(System.Globalization.CultureTypes.AllCultures)
End
Sub
Private
Sub
ComboBox1_SelectedIndexChanged(sender
As
Object
, e
As
EventArgs)
Handles
ComboBox1.SelectedIndexChanged
ListBox1.Items.Clear()
Dim
ci =
TryCast
(ComboBox1.SelectedItem, System.Globalization.CultureInfo)
If
ci
Is
Nothing
Then
Return
Else
System.Threading.Thread.CurrentThread.CurrentCulture = ci
End
If
TextBox1.Text = Now.ToString(
"G"
)
TextBox2.Text = 1234.5678D.ToString(
"G"
)
ListBox1.Items.Add($
"Name = {ci.Name}"
)
ListBox1.Items.Add($
"EnglishName = {ci.EnglishName}"
)
ListBox1.Items.Add($
"NativeName = {ci.NativeName}"
)
ListBox1.Items.Add($
"DisplayName = {ci.DisplayName}"
)
ListBox1.Items.Add($
"IetfLanguageTag = {ci.IetfLanguageTag}"
)
ListBox1.Items.Add($
"TwoLetterISOLanguageName = {ci.TwoLetterISOLanguageName}"
)
ListBox1.Items.Add($
"ThreeLetterISOLanguageName = {ci.ThreeLetterISOLanguageName}"
)
ListBox1.Items.Add($
"ThreeLetterWindowsLanguageName = {ci.ThreeLetterWindowsLanguageName}"
)
ListBox1.Items.Add($
"LCID = {ci.LCID}"
)
End
Sub
各カルチャの Name が、My.Application.ChangeCulture に渡せる文字列となりますが、
先の例のように、細かい制御ができないなどの理由から、「CurrentCulture を指定」するか
「変換時にカルチャを明示する」方が確実かもしれません。(自分は後者を使うことが多い)
投稿者
Coleman
 (社会人)   投稿日時
2020/10/20 11:22:04
魔界の仮面弁士さま、いつもご丁寧にご説明頂きありがとうございます。
なるほど。色々と勉強してみます。
ありがとうございました。