アカウント名:
パスワード:
日本国内だけで利用されるから、タイムゾーン決め打ちで自前の時刻処理を使ってるんだね
今回のはいわゆるタイムゾーンのせいではない。逆に自前処理だったら問題は小さかった。変数の値をファイル保存/読み込み処理を、何も考えずに開発言語の標準ライブラリにお任せしたからこんな問題が起きた。変数の値を自前でファイル保存してればいわゆるタイムゾーンの問題(時差で多少狂う程度の小さな問題)だけで済んだ。
#極論を言えばxamarinのせい!w
それがホントならxamarin何やってんのって感じだな
いや、ロケールをデフォルト(実行環境依存)にしていたから起きるわけで、プログラマの責任だよ今は発生する場面がなさそうだけど、小数点(カンマとドット)も同じ問題を孕んでる
全部 ISO 基準にしろよ、と思うかもしれないが、出力結果がどう使われるかは設計次第なわけで、人が読むテキストなのか機械が読むテキストなのかを区別するのはプログラマの責任人が読むテキストなら、現地環境で可読性の高い現地ロケールで出力されて欲しいからね
Dateをシリアライズして保存するのにロケールに依存する必要なんかなくないか?「保存用の保存」してロケールに依存しちゃうんじゃxamarinおかしいっしょ「表示用の文字列化して保存、読み込んだ後Dateに変換」してるんだったらプログラマがおかしいけど。
> Ver.1.2.2で混入したものとみられている。らしいから、バイナリだった保存を「読めたほうが良いか!」と文字列化/復元に変えてやっちゃった、とかかなぁ
ぶっちゃけバイナリだからミスしないわけでもないし
シリアライズ値でロケールに依存しないっていうと、UNIXエポック時間なんかがいいのかな
シリアライズ元のDate自体がロケールに依存してないのかな。サマータイムとか依存してたらプログラム上は表示以外はずっとUNIXエポックのまま扱わない限り問題起きそう
Unix timeで扱うとバグを生むからこういうライブラリがあるのよ
ただ単にファイル上での日付の形式を明確にしとけば良かったてだけの話よね。悪いのはプログラマ。
#3994406 はウソですね。.NETの標準ライブラリ関数の使い方が問題です。
DateTime.ToString メソッド (System) | Microsoft Docshttps://docs.microsoft.com/ja-jp/dotnet/api/system.datetime.tostring [microsoft.com]
DateTime.Parse メソッド (System) | Microsoft Docshttps://docs.microsoft.com/ja-jp/dotnet/api/system.datetime.parse [microsoft.com]
いずれも引数にロケールを指定して日付⇔文字列の変換が可能です。その指定を省略すると現在のロケールに応じた処理となるので今回のような問題が発生します。Xamarin関係ないですし、自前でファイル保存する必要もありません。
某社にいたとき、海外支社から上がってきたプログラムがテストを通らなかったことを思い出した現地の単体テストは通っているんだろう、とソースを読んでみたら日付を文字列化して月名で判断していた orz
つまり、ToString()すると英語圏だと "15-Mar-2021" とかになるそこに"Jan"が含まれていれば1月、"Feb"が含まれていれば2月、"Mar"が含まれていれば3月……のように月を調べていた日本語環境だとToString()で "2021/03/15" や "2021年3月15日" になるから英語名が含まれないどの条件にも引っかからないわけ
# なんのことはない、月をDateTime.Monthで取るよう修正した
"Jun"が7月で"Jul"が6月になるのがお約束
ToString("yyyyMMdd")のようにしていればロケールのことを忘れてても普通に動いた。これが自前処理ToString()のように「何も考えずに」お任せすると今回のような問題が起きる。
引数なしのtostringは人間が読める自然な形式に変換するものです。もっと言うと表示用の文字列に変換するものです。つまり何も考えず誤用した結果です。
時間が関わるプログラムは素人だけど(というか素人だからこその疑問だけど)、日時を何も考えずに取り出してきたらただ一つの数値が出てくるようなものじゃないんだね?NTFSみたいに1601年1月1日0時0分0秒から何100ナノ秒経過したかを示す整数値とか、Excelみたいに1900年1月1日(or 1904年)から何日経過したかを示す実数値とか、そういうのがデフォルトだと思ってたわ。
# 科学的なプログラムならかじったことあるけど、月曜日に計算した場合と金曜日に計算した場合とで結果が変わるようにプログラムする機会なんて無いからね。
内部的にはそういう数値だよ。C#は日付の数値を日付文字列に変換したり、逆に日付文字列を日付の数値として読み込んでくれる機能がある。その機能を使って起きた問題。
曜日は問題じゃないの経過時間の計算とかで困るの。エクセルも表面上はOSのタイムゾーン見てるから気をつけないとハマる。
Xamarinが悪い!に持っていきたいコメをちょくちょく見かけますね。使われると都合悪い人?
より多くのコメントがこの議論にあるかもしれませんが、JavaScriptが有効ではない環境を使用している場合、クラシックなコメントシステム(D1)に設定を変更する必要があります。
UNIXはただ死んだだけでなく、本当にひどい臭いを放ち始めている -- あるソフトウェアエンジニア
決め打ち (スコア:0)
日本国内だけで利用されるから、タイムゾーン決め打ちで自前の時刻処理を使ってるんだね
Re: (スコア:0)
今回のはいわゆるタイムゾーンのせいではない。逆に自前処理だったら問題は小さかった。
変数の値をファイル保存/読み込み処理を、何も考えずに開発言語の標準ライブラリにお任せしたからこんな問題が起きた。
変数の値を自前でファイル保存してればいわゆるタイムゾーンの問題(時差で多少狂う程度の小さな問題)だけで済んだ。
#極論を言えばxamarinのせい!w
Re:決め打ち (スコア:0)
それがホントならxamarin何やってんのって感じだな
Re:決め打ち (スコア:3, 興味深い)
いや、ロケールをデフォルト(実行環境依存)にしていたから起きるわけで、プログラマの責任だよ
今は発生する場面がなさそうだけど、小数点(カンマとドット)も同じ問題を孕んでる
全部 ISO 基準にしろよ、と思うかもしれないが、出力結果がどう使われるかは設計次第なわけで、人が読むテキストなのか機械が読むテキストなのかを区別するのはプログラマの責任
人が読むテキストなら、現地環境で可読性の高い現地ロケールで出力されて欲しいからね
Re: (スコア:0)
Dateをシリアライズして保存するのにロケールに依存する必要なんかなくないか?
「保存用の保存」してロケールに依存しちゃうんじゃxamarinおかしいっしょ
「表示用の文字列化して保存、読み込んだ後Dateに変換」してるんだったらプログラマがおかしいけど。
> Ver.1.2.2で混入したものとみられている。
らしいから、バイナリだった保存を「読めたほうが良いか!」と文字列化/復元に変えてやっちゃった、とかかなぁ
Re: (スコア:0)
ぶっちゃけバイナリだからミスしないわけでもないし
Re: (スコア:0)
シリアライズ値でロケールに依存しないっていうと、UNIXエポック時間なんかがいいのかな
シリアライズ元のDate自体がロケールに依存してないのかな。サマータイムとか
依存してたらプログラム上は表示以外はずっとUNIXエポックのまま扱わない限り問題起きそう
Re: (スコア:0)
Unix timeで扱うとバグを生むからこういうライブラリがあるのよ
Re: (スコア:0)
Re: (スコア:0)
ただ単にファイル上での日付の形式を明確にしとけば良かったてだけの話よね。
悪いのはプログラマ。
Re:決め打ち (スコア:1)
#3994406 はウソですね。.NETの標準ライブラリ関数の使い方が問題です。
DateTime.ToString メソッド (System) | Microsoft Docs
https://docs.microsoft.com/ja-jp/dotnet/api/system.datetime.tostring [microsoft.com]
DateTime.Parse メソッド (System) | Microsoft Docs
https://docs.microsoft.com/ja-jp/dotnet/api/system.datetime.parse [microsoft.com]
いずれも引数にロケールを指定して日付⇔文字列の変換が可能です。
その指定を省略すると現在のロケールに応じた処理となるので今回のような問題が発生します。
Xamarin関係ないですし、自前でファイル保存する必要もありません。
Re:決め打ち (スコア:1)
某社にいたとき、海外支社から上がってきたプログラムがテストを通らなかったことを思い出した
現地の単体テストは通っているんだろう、とソースを読んでみたら日付を文字列化して月名で判断していた orz
つまり、ToString()すると英語圏だと "15-Mar-2021" とかになる
そこに"Jan"が含まれていれば1月、"Feb"が含まれていれば2月、"Mar"が含まれていれば3月……のように月を調べていた
日本語環境だとToString()で "2021/03/15" や "2021年3月15日" になるから英語名が含まれない
どの条件にも引っかからないわけ
# なんのことはない、月をDateTime.Monthで取るよう修正した
Re: (スコア:0)
"Jun"が7月で"Jul"が6月になるのがお約束
Re: (スコア:0)
ToString("yyyyMMdd")のようにしていればロケールのことを忘れてても普通に動いた。これが自前処理
ToString()のように「何も考えずに」お任せすると今回のような問題が起きる。
Re: (スコア:0)
引数なしのtostringは人間が読める自然な形式に変換するものです。
もっと言うと表示用の文字列に変換するものです。
つまり何も考えず誤用した結果です。
Re: (スコア:0)
時間が関わるプログラムは素人だけど(というか素人だからこその疑問だけど)、日時を何も考えずに取り出してきたらただ一つの数値が出てくるようなものじゃないんだね?
NTFSみたいに1601年1月1日0時0分0秒から何100ナノ秒経過したかを示す整数値とか、Excelみたいに1900年1月1日(or 1904年)から何日経過したかを示す実数値とか、そういうのがデフォルトだと思ってたわ。
# 科学的なプログラムならかじったことあるけど、月曜日に計算した場合と金曜日に計算した場合とで結果が変わるようにプログラムする機会なんて無いからね。
Re: (スコア:0)
内部的にはそういう数値だよ。
C#は日付の数値を日付文字列に変換したり、逆に日付文字列を日付の数値として読み込んでくれる機能がある。その機能を使って起きた問題。
Re: (スコア:0)
曜日は問題じゃないの経過時間の計算とかで困るの。エクセルも表面上はOSのタイムゾーン見てるから気をつけないとハマる。
Re: (スコア:0)
Xamarinが悪い!に持っていきたいコメをちょくちょく見かけますね。
使われると都合悪い人?