none
dt = DateTime.Today; が何故か0001/01/01 となる RRS feed

  • 質問

  • 以下の不明な結果で困っています。

    Datetime dt;

    dt = DateTime.Today;

    というコードで、1度目にこのコードを通ると必ず0001/01/01 となり、

    2度目でやっと本当の本日の値を返します。

    どんな原因が考えられるでしょうか?

    どうぞ、よろしくお願い致します。

    2012年1月16日 16:05

回答

  • DateTime dt はどこに書いていますか?
    クラスのフィールド変数なのであれば、yearBox_TextChanged あたりで書き換えていると言うことはないですか?

    yearBox で 2012 が入った瞬間、dt を 2012/01/01 に書き換えていれば、monthBox.Text に到達する時点で 2012/01/01 になっているかもしれませんね。


    質問スレッドで解決した場合は、解決の参考になった投稿に対して「回答としてマーク」のボタンを押すことで、同じ問題に遭遇した別のユーザが役立つ投稿を見つけやすくなります。
    • 回答としてマーク Crack Tone 2012年1月23日 21:01
    2012年1月22日 21:50
    モデレータ

すべての返信

  • 二行目にブレークポイントを張って値を確認している、とか。
    2012年1月16日 16:46
  • 最初のクラス定義がDateTimeではなくDate「t」imeとtが小文字になっているので、自作クラスの可能性があります。

    ↑この書き込みは間違いです。紛らわしくなるだけなので削除してしまいたいですが、galacoさんの発言の意味が通らなくなってしまうので、一旦この状態にしてきます。

    以後こういう事が無いよう最大限気を付けたいと思います。失礼しました。(削除した方が適切ならそうさせて頂きます)


    2012年1月17日 13:44
  • 仮に自作クラスだったとして、DateTime.Today を入れられるクラスってどんなのですか?
    2012年1月17日 15:28
  • 仮に自作クラスだったとして、DateTime.Today を入れられるクラスってどんなのですか?


    まあ、C# には暗黙の変換機能があるので、そういう型は簡単につくれますが、おそらく記述ミスでしょうね。

    Hongliang さんが書かれているように、ブレークポイントを dt = DateTime.Today; という行に設定しているのではないでしょうか?

    dt = DateTime.Today; の次の行にセットしないと、まだ dt への代入が完了していないので dt の中身は初期値 (0001/01/01) が表示されるという結果になるかと思います。

     

    2012年1月20日 8:18
  • ご指摘のように、

    Datetime dt;

    は、

    DateTime dt;

    の間違いでした。とんでもない記述ミスで、申し訳ありません。

    で、

    dt = DateTime.Today

                yearBox.Text = dt.Year.ToString();

                monthBox.Text = dt.Month.ToString();

                dayBox.Text = dt.Day.ToString();

    というコードですが、

    2012/1/1

    という値がそれぞれのテキストボックスに入力されてしまいます。(実際、)

    何故でしょうか?

    yearBox.Text = dt.Year.ToString(); のところでは、dtが2012/1/23 なのに、

    monthBox.Text = dt.Month.ToString(); 以降は、dtが2012/1/1になります。

    よろしくお願いします。

    2012年1月22日 18:20
  • DateTime dt はどこに書いていますか?
    クラスのフィールド変数なのであれば、yearBox_TextChanged あたりで書き換えていると言うことはないですか?

    yearBox で 2012 が入った瞬間、dt を 2012/01/01 に書き換えていれば、monthBox.Text に到達する時点で 2012/01/01 になっているかもしれませんね。


    質問スレッドで解決した場合は、解決の参考になった投稿に対して「回答としてマーク」のボタンを押すことで、同じ問題に遭遇した別のユーザが役立つ投稿を見つけやすくなります。
    • 回答としてマーク Crack Tone 2012年1月23日 21:01
    2012年1月22日 21:50
    モデレータ
  • 最初の投稿には「1度目にこのコードを通ると必ず0001/01/01 となり、2度目でやっと本当の本日の値を返します。」と書かれています。
    しかし、2度目の投稿には「2012/1/1 という値がそれぞれのテキストボックスに入力されてしまいます。」と書かれています。
    これは、問題が異なっている…というか、現象が逆転していると思うのですが、本当は何が発生しているのでしょうか。


    Jitta@わんくま同盟
    2012年1月23日 12:51
  • 単純に、
    DateTime dt;
    private void dateBtn_Click(object sender, EventArgs e)
            {
                dt = DateTime.Today;
                yearBox.Text = dt.Year.ToString();
                monthBox.Text = dt.Month.ToString();
                dayBox.Text = dt.Day.ToString();
            }
    というコードなのです。
    yearBox.Text = dt.Year.ToString();
    のコードで止めて値を確認すると、dt は今日の日付になっています。
    ただし、
    private void yearBox_TextChanged(object sender, EventArgs e)
            {
                SetWeekDayLabel();
            }
    というイベントを作ってあり、
    private void SetWeekDayLabel()
            {
                if (DateTime.TryParse(yearBox.Text.ToString() + "/" + monthBox.Text.ToString() + "/" +
                    dayBox.Text.ToString(), out dt))
                    weekLbl.Text = dt.DayOfWeek.ToString().Substring(0, 3);
                else
                    weekLbl.Text = null;
            }
    というコードを通過すると、
    monthBox.Text = dt.Month.ToString();
    のコードの所では、dt が
    0001/01/01
    という値になってしまうのです。
    今までこの部分を紹介せずに解決を求めてしまい、申し訳ありませんでした。

    この

     if (DateTime.TryParse(yearBox.Text.ToString() + "/" + monthBox.Text.ToString() + "/" +
                    dayBox.Text.ToString(), out dt))
    のときに、dtの値が変わってしまったようです。
    このout dt というところに
    DateTime dTime = dt;
    とした dTime でも入れておけば、dt の値が変わらないでよかったと気づきました。
    皆様、申し訳ありませんでした。これで、解決しました。

    • 編集済み Crack Tone 2012年1月23日 21:00 途中で、解決しました
    2012年1月23日 20:06
  • 自分のミスに気付くのが遅れてしまいましたが、解決の糸口となったご指摘でした。

    ありがとうございます。

    2012年1月23日 21:02
  • ブレークポイントだけでなく、ステップ実行(ステップイン)を使ってみてください。
    そうすれば、どのような順番でコードが実行されるか確認できます。


    質問スレッドで解決した場合は、解決の参考になった投稿に対して「回答としてマーク」のボタンを押すことで、同じ問題に遭遇した別のユーザが役立つ投稿を見つけやすくなります。
    2012年1月23日 22:49
    モデレータ
  • DateTime dt;
    
    private void dateBtn_Click(object sender, EventArgs e)
    {
        dt = DateTime.Today;
        yearBox.Text = dt.Year.ToString();
        monthBox.Text = dt.Month.ToString();
        dayBox.Text = dt.Day.ToString();
    }
    
    private void yearBox_TextChanged(object sender, EventArgs e)
    {
        SetWeekDayLabel();
    }
    
    private void SetWeekDayLabel()
    {
        if (DateTime.TryParse(yearBox.Text.ToString()
                + "/" + monthBox.Text.ToString() + "/"
                + dayBox.Text.ToString(), out dt))
            weekLbl.Text = dt.DayOfWeek.ToString().Substring(0, 3);
        else
            weekLbl.Text = null;
    }
    

    というコードなのです。
    yearBox.Text = dt.Year.ToString();
    のコードで止めて値を確認すると、dt は今日の日付になっています。
    monthBox.Text = dt.Month.ToString(); のコードの所では、dt が
    0001/01/01
    という値になってしまうのです。

    このout dt というところに
    DateTime dTime = dt;
    とした dTime でも入れておけば、dt の値が変わらないでよかったと気づきました。

    修正方法は、そうではありません。これは、アクセス境界の問題です。SetWeekDayLabel と dateBtn_Click で同じ変数を使っていることが問題です。この問題の修正方法は、値を退避しておく、なんてことではありません。

    修正方法は、dateBtn_click と SetWeekDayLabel で別のワーク変数を使う、それぞれのメソッドの中でワーク変数を宣言することです。dt をワーク用の変数として用いており、ワーク変数を一箇所で宣言しようとしているのであれば、他にも類似の障害が多数含まれていることが懸念されます。

    また、WeekLbl.Text への設定値は、null ではなく、string.Empty の方が良いでしょう。

    おっと、string の値を ToString() するのも、不要ですよね。


    Jitta@わんくま同盟
    2012年1月30日 12:02