'2009-09-31'のようなユーザー入力に対応するためにC#での日付入力を許容するエレガントな方法はありますか(たとえば、9月31日は存在せず、DateTime.Parseがチョークします)?理想的には、これを10月1日として解析したいと思います(たとえば、可能な限り最新の日付とオーバーフロー)。
6 に答える
これがあなたのために直接処理されるとは思いません。あなたができることは、日付を3つの別々の整数として自分で解析することです:
- 2009 を解析し、2009 年 1 月 1 日の DateTime を作成します
dt = dt.AddMonths(8)
09 を解析して 1 を減算し、9 月 1 日を取得するために呼び出します- 31 を解析して 1 を引いてから呼び出します
dt.AddDays(30)
これは、2009/13/01 のようなものを 2010 年 1 月 1 日を意味するように処理します。
ユーザー入力で誤った日付を回避する 1 つの方法は、最初のインスタンスで発生させないようにすることです。つまり、日付ピッカー コントロールを使用します。
を使用するのは DateTime.TryParse
どうですか?
指定されたカルチャ固有の書式情報と書式設定スタイルを使用して、日付と時刻の指定された文字列表現を等価の DateTime に変換し、変換が成功したかどうかを示す値を返します。
このMSDN ページには、使用例が示されています。
DateTime.DaysInMonth
この方法は非常に役立つと思いますTryParse
....あなたが話しているロジックを実装することができます
(道徳的に) このような入力を処理しようとすべきではありません。1900 年 2 月 29 日は 1900 年 3 月 1 日として解釈されます (1900 年 2 月 29 日は 1900 年 2 月 28 日の翌日と解釈される可能性がありますが、存在しないため、1900 年 2 月 28 日以降の実際の日を移動します) または 2 月として解釈されます。 1900 年 2 月 28 日 (1900 年 2 月 29 日は 1900 年 2 月の最終日と解釈できるため)? もう 1 つの状況は、ユーザーが「2009-3-3」と入力するつもりだったのに、速くてベタベタした指のために誤って「2009-3-33」と入力した場合です。その後、エラーがキャッチされるのではなく、カスタム パーサーがこれを 2009 年 4 月 2 日などに飲み込みます。このような状況のため、入力のみを行い、無効な入力が発生した場合はユーザーに通知する必要があります。DateTime.TryParse
それがあなたがすべきことです。
さて、そのような入力を処理することが要件である場合。私は次の行に沿って何かを使用します:
static DateTime Parse(int year, int month, int day) {
DateTime date;
if (month < 1 || month > 12) {
int direction = month < 1 ? 1 : -1;
do {
month += direction * 12;
year -= direction;
} while (month < 1 || month > 12);
}
int daysInMonth = DateTime.DaysInMonth(year, month);
if (day < 1 || day > daysInMonth) {
date = new DateTime(year, month, daysInMonth);
int difference = day - daysInMonth;
date = date.AddDays(difference);
}
else {
date = new DateTime(year, month, day);
}
return date;
}
コンパイラは解析できない例外をスローするだけなので、この種の問題に対しては独自のパーサーを作成する必要があります。
ルール #1: できるだけ合理的に、ユーザーが最初から無効なデータを入力できないようにします。
Windows フォームを使用している場合は、可能な限り DateTimePicker を使用してください (ただし、ロケールに関しては制限があります)。または、アプリが ASP.NET にある場合は、Calendar または AJAX Control Toolkit コントロールの 1 つを使用しますが (正確な名前は今は忘れました)、カレンダーで小さなポップアップが表示されます。
後でこのアプリケーションをローカライズする必要がある場合は、日付コンポーネントを別のフィールドに分離する (またはそのように解析する) ことを強くお勧めします。