C# 入門講座
Visual Studio 2005 Visual Studio 2008 Visual Studio 2010 Visual Studio 2012 Visual Studio 2013 Visual Studio 2015 Visual Studio 2017 Visual Studio 2019 Visual Studio 2022

第6回 文字・数値・日付のあつかい

2022/1/9

この記事が対象とする製品・バージョン

Visual Studio 2022 Visual Studio 2022 対象です。
VS2019 Visual Studio 2019 対象です。
VS2017 Visual Studio 2017 対象です。
VS2015 Visual Studio 2015 対象です。
VS2013 Visual Studio 2013 対象です。
VS2012 Visual Studio 2012 対象ですがそこそこ画面が異なる場合があります。
VS2010 Visual Studio 2010 対象ですがそこそこ画面が異なる場合があります。
VS2008 Visual Studio 2008 対象ですがそこそこ画面が異なる場合があります。
VS2005 Visual Studio 2005 対象ですがそこそこ画面が異なる場合があります。
VS.NET 2003 Visual Studio 2003 対象外ですがほとんどの操作は同じなので参考になります。
VS.NET 2002 Visual Studio (2002) 対象外ですがほとんどの操作は同じなので参考になります。

目次

 

1.型

プログラムの経験がほとんどない方は意外に思われるかもしれませんが、プログラムの世界では文字と数値と日付は明確に区別されます。たとえば、文字をデータベースに書き込むときと、日付をデータベースに書き込むときとでは違う仕組みを使います。日付を書き込む仕組みを使って文字を書き込もうとすると多くの場合エラーになります。

そのため、プログラムの中で文字・数値・日付をあつかう場合(つまりほとんどの場合)はこれらの取り扱いをちゃんと知っていなければなりません。

今回はこのような文字・数値・日付の取り扱い方の違いと、簡単な取り扱い例を説明します。

このような区別を「型」(かた)を呼びます。データ型とも言います。

型には文字・数値・日付の他にもたくさんのものがあります。また、「数値」と一口に言ってもコンピューター内部の処理の違いによってさらに細かくいくつかの型に分かれます。(整数型・長整数型・十進型・浮動小数点型など)。

「文字」についても「文字」と「文字列」(もじれつ)は別の型です。「文字」といった場合は1文字、「文字列」と言った場合は1文字以上の連続する文字を指します。プログラムの中で扱う文字は99%「文字列」です。「文字列」という言葉は重要なので覚えておいてください。

 

初心者の方にはなぜ型を区別しなくてはならないのか疑問に感じる方もいらっしゃるでしょう。確かにこれらを区別しないという考え方もあります。しかし多くのプログラマーたちはこれらを区別した方がプログラムにとって大きなメリットがあると考え、現在C#を含めほとんどのプログラム言語では型を区別します。

型を区別する最大のメリットは間違いの防止です。今の時点ではピンとこないかもしれませんが、C#自体がこれらを区別してあつかうときに最高の性能・機能を発揮するように作られているので「郷に入れば郷に従え」です。とりあえず、メリットが見えなくても割り切ってまずはどんなものなのか理解してみましょう。

 

2." は文字列を作る

 

まず、" " で囲んだものは文字列になるということを説明します。

 

単純なプログラムを使って、このことを確かめてみましょう。

一緒にプログラムしながら読んでみることをお勧めします。

 

Windowsフォームアプリのフォームにボタンを1つ貼り付けて、Clickイベントハンドラーを次のようにプログラムしてみてください。

private void button1_Click(object sender, EventArgs e)
{ MessageBox.Show("こんにちは"); }

 ■リストA-1

これはもうお分かりと思いますが、実行すると画面に「こんにちは」と表示されます。

 

このプログラムは次のように書くこともできます。

private void button1_Click(object sender, EventArgs e)
{ string st; st = "こんにちは"; MessageBox.Show(st); }

■リストA-2

実行するとリスト1とまったく同じ動作をすることがわかります。

st = "こんにちは";
MessageBox.Show(st)

この部分をみれば、特に知識がなくても感覚的に納得できますよね。st が「こんにちは」という文字列を表しているわけですね。

ここで st は変数と呼ばれるもので、この例では st という名前にしましたが、x でも y でも hello でも自分で好きな名前を付けることができます。名前をつけているのが1行目の string st の部分です。変数については別の機会に説明しますのでここでは1行目は特に気にしないで下さい。今回はこの1行目よりも「こんにちは」などの文字の方がテーマです。

さて、プログラムをさらに改造して次のようにしてみてください。

//これはおかしな例です。
string st;
st = "こんにちは";
MessageBox.Show("st");

■リストA-3

前の例との違いは MessageBox.Show("st") St の前後に " が付いている点です。この状態で実行すると今度は「こんにちは」ではなく、「st」と表示されます。

このように 記号 " (ダブルクォーテーション)には特別な意味があります。 " ではさまれているものは、意味のない文字列 としてあつかわれるのです。

ですから、次のプログラムでは「MessageBox」と表示されます。


MessageBox.Show("MessageBox");

■リストA-4

一方、次のプログラムはエラーになります。

//これはエラーです。 
MessageBox.Show(MessageBox);

■リストA-5

リストA-4ではMessageBoxの前後が " でくくられているのでMessageBoxは意味のない文字列として扱われますから問題ありません。リストA-5ではMessageBoxの前後に " がありませんので MessageBoxは意味のある命令として扱われます。そうするとMessageBox.Show(MessageBox)というプログラムはキーワードの使い方がおかしいのでエラーになってしまうわけです。

 

お気づきと思いますが、Visual Studio は文字列を赤茶色い色の文字で表示するので、文字の色を見ることで、それが文字列なのかそうではないのか区別することもできます。

 

別の視点でも眺めてみましょう。次の例はエラーになります。

string st;
st = こんにちは;
MessageBox.Show(st);

 ■リストA-6

どうしてエラーかというと、「こんにちは」に " がついていないので、「こんにちは」が意味のある命令として解釈されるからです。しかし実際にはC#には「こんにちは」という命令はありません。ですからエラーになるのです。

この " の性質を初級プログラマーはよく覚えておいてください。

 

3. + は文字列をつなぐ

+ を使うと2つの文字列を結合することができます。

次のプログラムはその単純な例です。

private void button1_Click(object sender, EventArgs e)
{ string st1;
    string st2;
    string st3;

    st1 = "源";
    st2 = "義家";
    st3 = "頼朝";

    MessageBox.Show(st1 + st2);
    MessageBox.Show(st1 + st3);
}

■リストB-1

このプログラムを実行すると、はじめに「源義家」と表示され、次に「源頼朝」と表示されます。

源義家は平安時代の武将で、後三年の役で活躍しました。義家の孫の孫が平家を打ち破って鎌倉幕府を開いた源頼朝です。

リストB-1を見れば分かるとおり、表示する文字列は 記号 + を使ってプログラム中で合体させています。

変数と文字列

文字列の結合

■図1

このように + を使うと文字列を結合させることができます。直感的に理解できることと思います。

リストB-1は次のように書くこともできます。

private void button1_Click(object sender, EventArgs e)
{
   MessageBox.Show("源" + "義家");
    MessageBox.Show("源" + "頼朝");
}

■リストB-2

しかし、"源" + "頼朝" と書くくらいならはじめから"源頼朝"と書くのが普通なので、実際にリストB-2のようなプログラムを見かけることはないでしょう。勉強用のサンプルというところです。

今度は、もう少し複雑にした次の例を考えて見ましょう。

private void button1_Click(object sender, EventArgs e)
{
   string st1 = "義家";
    string st2 = "頼朝";
    string st3 = "平安";
    string st4 = "鎌倉";

    MessageBox.Show("源" + st1 + "は" + st3 + "時代に死にました。");
    MessageBox.Show("源" + st2 + "は" + st4 + "時代に死にました。");
}

■リストB-3

こうなってくると、どれが " の中にあって どれが " の外にあるのかとても分かりにくいですね。初心者はこのようなときに " の使い方を間違ってよくエラーになるようです。皆さんも気をつけてください。Visual Studio 2005以上ならば " の中にある文字は茶色く表示されるので少しはわかりやすくなっています。

文字列の結合

■図2

文字列の結合が複雑になってくるとプログラムが見にくくなってくるので、Visual Studio 2013(C# 6.0)以上では文字列補間という機能が導入され、さらに簡単な書き方ができるようになっています。

次の例はリストB-3と同じ結果になります。

private void button1_Click(object sender, EventArgs e)
{
   string st1 = "義家";
    string st2 = "頼朝";
    string st3 = "平安";
    string st4 = "鎌倉";

    MessageBox.Show($"源{st1}{st3}時代に死にました。");
    MessageBox.Show($"源{st2}{st4}時代に死にました。");
}

■リストB-4

文字列補間機能を使う場合、+ を使わないで文字列を結合できます。リストB-4のように文字列の中に { } で囲んで変数を埋め込むことができます。

先頭の " の前に $ が付いているのがポイントで、$をつけると、文字列補間機能を使用するという意味になります。$ をつけないと通常の文字列になるのでこの例では「源{st1}は{st3}時代に死にました。」などと表示されます。

 

4.いろいろな文字列

4-1.改行の書き方あれこれ

C#では、次のようにして改行を表現することができます。

private void button1_Click(object sender, EventArgs e)
{
   MessageBox.Show(@"あいうえお
かきくけこ
さしすせそ");
}

■リストC-1

文字列の改行

この例では文字列の先頭に @ がついていることに注意してください。@ がついている文字列を逐語的文字列(ちくごてきもじれつ)と呼びます。逐語的文字列の場合C#はできるだけ、プログラムに書いてある通りの文字列として解釈してくれます。

 

特別な値 Environment.NewLine (読み方:Environment = エンバイロメント、NewLine = ニューライン)を使って改行を表現することもできます。

private void button1_Click(object sender, EventArgs e)
{
   MessageBox.Show("あいうえお" + Environment.NewLine + "かきくけこ" + Environment.NewLine + "さしすせそ");
}

■リストC-2

これを実行すると、Environment.NewLine の位置で改行され、上記と同じように表示されます。

 

さきほどの文字列補間機能と組み合わせて次のように書くこともできます。上の例よりは少しだけプログラムが短くなります。

private void button1_Click(object sender, EventArgs e)
{
    MessageBox.Show($"あいうえお{Environment.NewLine}かきくけこ{Environment.NewLine}さしすせそ");
}

文字列補間機能を使う場合は文字列の先頭に $ をつけるのをお忘れなく。

 

C#ではある程度自由にプログラム自体を複数行に分けて書くこともできるので、プログラムの1行が長くなってしまうようならばこのように書くこともできます。

private void button1_Click(object sender, EventArgs e)
{
   MessageBox.Show("あいうえお" + Environment.NewLine
                  + "かきくけこ" + Environment.NewLine
                  + "さしすせそ");
}

 長い行のどこを改行すればプログラムが見やすくなるかはプログラマー個人個人の美意識によります。

Environment.NewLineの良いところは、OSによる改行コードの違いを吸収してくれるところです。WindowsとLinuxとでは改行コードが異なるのですが、Environment.NewLineは実行した環境に合わせた改行コードを使ってくれます。

Environment.NewLineのことをはじめて知ったとしても、これがEnvironmentオブジェクトのNewLineプロパティであるというということは前回の説明を読んでいれば気がつけるかもしれませんね。

 

C#ではこの他に次のように \r\n という特別な文字を使って改行を表すこともできます。

private void button1_Click(object sender, EventArgs e)
{
   MessageBox.Show("あいうえお\r\nかきくけこ\r\nさしすせそ");
}

これはC#の先祖であるC言語でも有効な伝統的な表現方法であり、この方法を今でも使っているプログラマーは多数います。この記述方法ではOSによる差異は吸収されませんので、Winodwsであれば\r\n、Linuxであれば\r のように自分でプログラム内で改行コードを切り分けるなどの工夫が必要になります。しかし、いろいろなOSで動く必要がないプログラムもたくさんありますから、Windows上でしか動かさないことがわかっている場合などはこの書き方でも問題はありません。

 

4-2.エスケープシーケンス

\r\n のような特別な文字の並びで特別な意味を表現できるものを エスケープシーケンス または エスケープ文字 と呼びます。

エスケープシーケンスを使うことで改行のように通常表現しにくいものを文字列内で表現できます。エスケープシーケンスは\r と \n 以外にも多数あり、必ず \ から始まります。

よく使うエスケープシーケンスは次の通りです。

エスケープシーケンス 意味
\" ダブルクォーテーション
\\ 円マーク (英語フォントではバックスラッシュ)
\r\n 改行(Windows)
\r 改行(LinuxとMacOSX以降)
\n 改行(MacOS9以前)
\t タブ
\u Unicode文字をUTF16で指定

 

エスケープシーケンスを使っても、表示する場所が対応していなければ無意味なことがほとんどです。たとえば、改行できない場所で改行は無意味ですし、タブが表示できない場所でタブは無意味です。

MessageBox.Showは改行もタブも表示してくれるので、次のコードは有効です。

private void button1_Click(object sender, EventArgs e)
{
   MessageBox.Show("あいうえお\tかきくけこ");
}

このように表示されます。

タブ付きの文字列

※環境によってはこれほど間があかない場合もあるようです。"あいうえ\tおかきくけこ"などと \t の位置を返ると間があくこともあります。タブの特性でもありますが、環境によって異なる点は私も理屈を説明できません。なぜでしょう。

 

文字列内で " や \ を表現したいときもエスケープシーケンスの出番です。

private void button1_Click(object sender, EventArgs e)
{
   MessageBox.Show("\"これいくらですか?\"\r\n\"\\1200です。\"");
}

ちょっと説明用に無理したので普段使わない感じの記号の使い方になってしまいました。実行すると次のようになります。

このレベルになるとパッと見でどうなっているのかわからなくなってしまいますが、Visual Studioは文字列内でエスケープシーケンスの部分は違う色で表示してくれるので助けになります。古いバージョンのVisual Studio(2017以前?)では通常の文字列と同じ色で表示します。

それにそもそもこんな使い方はほとんどしないのであまり心配する必要はありません。今はエスケープシーケンスの説明をしているのであえて複雑な例を紹介していますが、プログラム内でこのように固定の文字列を記述して表示するということはほとんどないでしょう。

 

\u は他とはちょっと使い方が異なっており、これに続けてUnicodeの文字コードをUTF16で入力します。

次の例ではこれを利用してUnicodeの絵文字からコーヒーを表示します。Unicodeの絵文字に対応したフォントでないと表示できないので、textBox1にフォントを指定するプログラムも含めました。フォントを指定するプログラムは入門講座では説明していませんが、フォント名とフォントサイトを指定するだけです。今回説明したいのはエスケープシーケンスの方なのでここにはあまり深入りしません。プロパティウィンドウを使ってあらかじめフォントをSagoe UI Emojiに設定しておいても良いです。

それから、この例を実行するためにはあらかじめtextBox1という名前のテキストボックスをフォームに配置しておく必要があります。念のため。

private void button1_Click(object sender, EventArgs e)
{
   textBox1.Font = new Font("Segoe UI Emoji", 24);
    textBox1.Text = "\u2615いかがですか?";
}

Unicodeの絵文字が表示されているTextBox

ところで、わざわざ文字コードで書かなくてもプログラムに直接絵文字を入力してしまうこともできます。

プログラムに直接絵文字を埋め込むこともできます

コーヒーの絵がさきほどと違うのはフォントの違いによるものです。

文字コードを意識したプログラムをするときは \u の記述方法を使うことが多くなると思いますが、そうでもなければ絵文字等直接入力してしまっても特に不都合はありません。

 

4-3.パス

Windowsのファイルのパスはフォルダーの区切り文字に \ を使用しているため、プログラムの中で何も考えずにパスを扱うと C# はエスケープシーケンスだと解釈してしまいます。

たとえば、次のプログラムは WriteAllTextメソッド(読み方:WriteAllText = ライトオールテキスト)を使って、ファイルに文字列を書き込もうとしているものです。

対象のファイルのフルパスと書き込む内容を両方文字列の引数で指定する必要があります。

private void button1_Click(object sender, EventArgs e)
{
   //この例はエラーになります。
    System.IO.File.WriteAllText("C:\test\text.txt", "あいうえお");
}

でも、この例だと \t がタブを表すエスケープシーケンスになってしまうので、意図したようなフォルダーとファイルを意味しません。そもそもパスにはタブを含むことができないので実行するとエラーになります。

簡単な解決方法はさきほどでてきた逐語的文字列です。文字列の先頭に @ をつけて、逐語的文字列にすればほとんどのエスケープシーケンスは無効になり、ファイルのパスは書いたままに解釈されます。

次の例は正常に動作します。

private void button1_Click(object sender, EventArgs e)
{
    System.IO.File.WriteAllText(@"C:\test\text.txt", "あいうえお");
}

 

4-4.少し整理

いろいろ出てきて話が複雑になってきました。ちょっとまとめましょう。C#の文字列には3種類あります。

1つ目は、" " で囲まれた普通の文字列です。2つ目は $" " で囲まれた文字列補間機能付きの文字列です。3つ目が @" " で囲まれた逐語的文字列です。この3つで全部です。

$ と @ が両方付く場合もあるので、これも入れると4種類です。この場合、文字列補間機能と逐語的文字列の両方の性質があります。C#上級編の勉強をしてもこれ以上種類は増えません。

文字列の種類 エスケープシーケンス
(\t や \r\n など)
文字列補間
( {st1} のようなもの)
通常の文字列 "こんにちは" ○ 機能します × 機能しません
文字列補間機能付きの文字列 $"こんにちは、{name}さん" ○ 機能します ○ 機能します
逐語的文字列 @"C:\test" × 機能しません × 機能しません
文字列補間機能付きの逐語的文字列 $@"C:\{folderName}" × 機能しません ○ 機能します

なお、$ と @ の両方をつける場合は $@ の順番でも @$ の順番でもどちらもOKです。

2019年リリースの C# 8.0 からはどちらの順番でも使用できるようになりました。それより前のC#では $@ の順番でしか使えませんでした。

 

5.数値

5-1.数値は直接記述する

数値をあつかう場合は文字列と違って " をつけずに直接書きます。

たとえば、次のプログラムは正常に動作し、実行すると 627 と表示されます。

private void button1_Click(object sender, EventArgs e)
{
   MessageBox.Show(627.ToString());
}

■リストD-1

627の後ろに ToString() とついているのは、627を文字列に変換するためです。

MessageBoxに表示できるのは文字列だけなので、文字列以外のものを表示したい場合は ToStringメソッド(読み方:ToString = トゥーストリング)で文字列に変換するなどします。

 

このプログラムは次のように書くこともできます。

private void button1_Click(object sender, EventArgs e)
{
   decimal x = 627;
    MessageBox.Show(x.ToString());
}

■リストD-2

decimal xの方は今回のテーマではないのであまり気にしないでください。簡単に説明すると数値型の変数 x を宣言しています。 

数値型にも何種類かあるのですが、decimal (読み方:decimal = デシマル)で宣言すると数値型の中でも「十進型」(じゅっしんがた)という型になり、整数も小数も表現できる変数になります。

 

数値の場合は +, -, *, / などを使って計算することもできます。 キーボードには日本の算数・数学で使われている掛け算の「×」と割り算の「÷」がないので代わりに * が掛け算、 / が割り算を表しています。

これらの記号を使った例は次の通りです。

private void button1_Click(object sender, EventArgs e)
{
    decimal x = 815.6M;

    decimal a1 = x + 3;
    MessageBox.Show(a1.ToString());

    decimal a2 = x - 3;
    MessageBox.Show(a2.ToString());

    decimal a3 = x * 3;
    MessageBox.Show(a3.ToString());

    decimal a4 = x / 3;
    MessageBox.Show(a4.ToString());
}

■リストD-3

変数 x を decimal で宣言しているので小数もちゃんと扱えます。

ただ、よくみると x に 815.6 をセットするときに、後ろに「M」がついているのがわかります。

このMは 815.6 という値を decimal として扱うということをC#に指示する意味です。このように型を明示する意図で使う文字がいくつかあり「型のサフィックス」と呼ばれます。

数値にMがついている

 

リストD-2では、この M が必要なかったのは値が整数だからです。値が小数の場合、C#は浮動小数点型(double)という型であると判断してしまいます。しかし、私たちはdecimalにしたいので、C#に、これはdecimalだと伝えるためにMをつけます。

 

話を元に戻しましょう。

+, -, *, /のような計算記号のことをC#では「演算子」(えんざんし)と呼びます。C#で使える計算用の演算子の表を載せておくので参考にしてください。

演算子 通称 機能
+ プラス・たす たし算
- マイナス・ひく ひき算
* アスタリスク・かける かけ算
/ スラッシュ・わる わり算
== イコール・ダブルイコール・は(わ) 等しいか調べる
% パーセント わり算をして、「あまり」を返す。

これ以外にもさまざまな演算子があります。

 

 

5-2.演算子と型

ところで、文字列の説明をしたときに「+」は文字列をつなぐと説明しました。数値の説明をしたときには「+」はたし算の記号であると説明しました。

このように同じ記号でも型によって意味が変わります。特にたし算と文字列の結合はどちらもプログラムでよく出てくるので + 記号の取り扱いに初心者は注意です。

次のプログラムはなんと表示されるかわかりますか?

このプログラムでは変数testの型の部分に var (読み方:var = バー)と書いています。varは特殊なキーワードで、簡単に説明すると変数の型はC#におまかせするという意味です。変数の宣言と値のセットを同時に行う場合だけvarを使って変数の型をC#にまかせることができます。Visual Studio 2008に搭載のC# 3.0以上でvarは使用できます。

private void button1_Click(object sender, EventArgs e)
{
   var test = "2" + "3";
    MessageBox.Show(test.ToString());
}

このプログラムでは + の前後の "2" と "3" は " で囲まれているため文字列です。そのため + の意味は文字列の結合になりますので、「23」と表示されます。

C#はtestを文字列型と判断します。

文字列型ですので、MessageBoxの行で .ToString() はなくても良いのですが、ちょっとひっかけであえて書いてみました。

 

それでは次のプログラムはどうでしょうか?

もうどこに注目すればよいかわかりますよね?

private void button1_Click(object sender, EventArgs e)
{
   var test = 2 + 3;
    MessageBox.Show(test.ToString());
}

このプログラムでは 2 と 3 が " に囲まれていないので数値と判断されます。そのため + はたし算ですから、「5」と表示されます。

ちなみに、このケースではC#はtestを整数型(int)と判断します。数値なのでMessageBoxの行で .ToString() を記述して文字列に変換しないとエラーになります。

 

では、次のプログラムはどうでしょうか?

private void button1_Click(object sender, EventArgs e)
{
   var test = 2 + "3";
    MessageBox.Show(test.ToString());
}

これは、もう入門講座の範囲をかなり超えてしまっています。

そもそもこのような紛らわしいプログラムは書くべきではありません。あなたがこのようなプログラムを書いたら先輩はNGを出すと思いますよ。

それでも実行はできます。この例では「23」と表示されます。文字列の方が"3"だから一瞬迷ってしまいますが、もし2 + "A"だったら、エラーになるか、「2A」になるかしか考えられないですよね。

 

6.日付と時刻

6-1.日付と時刻の表示形式

C#では日付と時刻を表す特別な表現方法は用意されていません。

特別な表現方法が用意されていない場合は、オブジェクトを使用することになります。日付と時刻の場合 DateTime (読み方:DateTime = デイトタイム)というオブジェクトが用意されています。

「オブジェクト」全般については初級講座で扱う予定です。ここではDateTimeだけについて扱い方を説明します。

 

次のプログラムは2020年6月27日を表すDateTimeオブジェクトを作成し、文字列として表示します。

private void button1_Click(object sender, EventArgs e)
{
   //2020年6月27日を表すDateTimeオブジェクトを作成
    DateTime day = new DateTime(2020, 6, 27);

    //文字列として表示
    MessageBox.Show(day.ToString());
}

■リストE-1

「文字列として表示」というところは 初心者に特に注意してもらいたい部分です。詳しく説明しましょう。

日付や時刻を画面に表示したり、印刷したりなど人間向けに表示するとき、それはDateTimeオブジェクトではなく文字列型です。

たとえば、2020年6月27日という日付は1つしかありませんが、これを画面に表示するための形式はたくさんあります。いくつか例を挙げてみます。

このような形式を書式と呼びます。

DateTimeオブジェクトはこのような表示用の書式とは無関係で、1つしかない日付の値自体を表現しています。画面などに表示する日付はDateTimeオブジェクトではなく文字列型です。

DateTimeオブジェクトを文字列型に変換する場合ToStringメソッドを使用します。さきほどのリストE-1でもMessageBoxで表示するときにはToStringメソッドを使って文字列型にしています。

DateTimeオブジェクトはプログラム内での存在

 

日付の値をどのような書式で表示するかは表示するときにプログラマーが指定します。

特に指定をしなかった場合はプログラムを実行している環境に依存します。Windowsの場合、ユーザーのコントロールパネルの地域と言語の設定に依存します。

コントロールパネルの地域と言語の設定

プログラムを作成した環境やユーザーではなく、実行している環境やユーザーである点に注意してください。

つまり、プログラマーが書式を指定しなかった場合、どのように表示されるかプログラマーには事前には予測できないということです。

日本人のWindowsの設定は大体同じだと思いますが、リストE-1を実行した結果何が起こるかは人によって違うかもしれません。私の場合「2020/06/27 0:00:00」と表示されました。

博士のワンポイントレッスン 「なんでわざわざDateTime?」
V太 V太:ちょとまて、ちょとまて!意味がわからないよ。わざわざDateTimeなんて使わないで、最初から文字列で"2020/06/27"と書けばいいんじゃないの?どのように表示されるかもはっきりしているし。
B子 B子:うーん。確かにそうかも。博士、どういうことですか?
V太 博士:うーむ。ちょっと考えてみて欲しい。日常生活の中で「日付」ってどういう風につかっているかのぉ?
B子 えっと、「明日は晴れ」とか、「来週は遠足」とか、「月末は忙しい」とか、「1週間後には返してください」とか、「去年は暑かった」とか、「後300日で東京オリンピック」とか?
V太 「明日」、「来週」、「月末」、「1週間後」、「去年」、「後300日」
V太 DateTimeの機能を使うとそういった日時や期間を簡単に求めることができるのじゃ。文字列にはそういう機能はない。だから、文字列で"2020/06/27"とプログラムしてしまうと、1週間後が何月何日か求めるプログラムを作るのはすごく大変なのじゃ。DateTimeだと AddDaysメソッドを使って1週間後の日付は簡単に求められるぞ。AddDaysの使用例は後で紹介しよう(リスト H-3)。
B子 なるほどねぇ。でも、実際に使ってみるまではピンとこないかも。
博士 他にも日付や時刻ならではの機能というのは結構いっぱいある。日付や時刻がプログラムの中にでてくるのだったら文字列ではなくDateTimeを使うようにの。

 

6-2.書式指定

表示するときに書式を指定する方法はいくつかあります。代表的なのはToStringメソッドの引数を使う方法です。

リストE-1のように引数なしでToStringメソッドを使用すると、どのように表示するかは環境(Windowsの場合、上記のコントロールパネルの設定)によって変わります。

ToStringメソッドに引数をつけると書式を指定できます。これを使えば、どのように表示されるか制御できます。

下記の例では変数に格納した日付を異なる書式で表示しています。

private void button1_Click(object sender, EventArgs e)
{
   //2020年6月27日を表すDateTimeオブジェクトを作成
    DateTime day = new DateTime(2020, 6, 27);

    //書式指定なし。実行環境の設定(Windowsのコントロールパネルなど)で書式化されます。
    MessageBox.Show(day.ToString());

    //2020年06月27日
    MessageBox.Show(day.ToString("yyyy年MM月dd日"));

    //20-06-27
    MessageBox.Show(day.ToString("yy-MM-dd"));
}

■リストE-2

書式は引数に独特の文字列で指定します。この文字列のことを書式指定文字列といいます。

書式指定文字列には、yyyyであれば西暦で4桁の年、MMは西暦で2桁の月、Mは西暦で1桁の月のように定められているものを組み合わせて使用します。

よく使う日付の書式は次の表のとおりです。曜日も書式で表現している点は覚えておくと良いと思います。

yyyy 年を4桁 例:2020 HH 24時間制の時間を2桁 例:15
yy 年を2桁 例:20 H 24時間制の時間を1桁または2桁 例:15
MM 月を2桁 例:06 hh 12時間制の時間を2桁 例:03
M 月を1桁または2桁 例:6 h 12時間制の時間を1桁または2桁 例:3
dd 日を2桁 例:27 mm 分を2桁 例:05
d 日を1桁または2桁 例:27 m 分を1桁 例:5
dddd 曜日 例:土曜日 ss 秒を2桁 例:46
ddd 曜日の短縮形 例:土 s 秒を1桁 例:46

・書式指定ではアルファベットの大文字と小文字が区別されるので注意してください。

・すぐ後で指定する文化の指定によって書式の意味が変わる場合があります。たとえば、日本の文化を指定しているときには gg は元号になります。 yyyy は4桁ではなくなります。

・「H」だけや「d」だけのように、1文字だけの書式は指定できません。1文字だけ指定する必要がある場合は特別に「%H」や「%d」のように前に「%」を付けます。

参考:カスタム日時書式指定文字列

https://docs.microsoft.com/ja-jp/dotnet/standard/base-types/custom-date-and-time-format-strings

 

書式指定文字列の中では定義されていない文字列はそのままその位置に出力されます。たとえば、「中」・「学」・「校」という文字は書式として定義されていないため、day.ToString("中学校") は day が何月何日でも「中学校」と表示されます。

day.ToString("中MM学校") だと MM は月2桁と定義されているため、たとえば、「中08学校」となります。すべての漢字を含めほとんどの文字は書式として定義されていないため自由に使用できます。「年」「月」「日」「時」「分」「秒」も自由に使用できます。

\ (非日本語フォントではバックスラッシュ)はここでもエスケープシーケンスとして特別な効果があります。ここでの \ の効果は直後の文字を書式指定文字ではない通常の文字として扱うものです。たとえば、ToString("yyyy")は年4桁になりますが、ToString(@"\y\y\y\y")はそのまま「yyyy」と出力されます。この文字列には @ がついていて、先ほど説明した逐語的文字列になっている点に注意してください。

日付の区切り文字である / は文化によっては - として出力される場合があると思います。どの環境でも確実に / と表示するためにはToString(@"yyyy\/MM\/dd")のようにエスケープを付けて \/ と書きます。

時刻の区切りによく使われる : についても同様です。

 

7.和暦と文化

日付の表示や値は文化により異なります。

日本人は西暦の日ではグレゴリオ暦を使用しており、これは世界の多数派です。

和暦は日本独特ですが、年の表現が異なるだけで月と日の表現はグレゴリオ暦と同じです。たとえば、アメリカの3月1日を和暦で表現しても必ず3月1日です。

しかし、世界には月と日が異なる文化もあります。

たとえば、日本人にとっての2020年6月27日は、驚くべきことにサウジアラビアの伝統的な暦(ヒジュラ暦)では1441年11月6日です。

グレゴリオ暦・和暦・ヒジュラ暦と3つの異なる日付の文化を紹介しましたが、世界には他にも異なる暦の文化があります。

 .NETは世界中で使用できるように設計されており、この「文化」を設定などで指定したり変更したりできます。プログラム自体はグレゴリオ暦で記述することになっているので、世界中どこに行っても変わりません。プログラマーのみなさんはグレゴリオ暦でプログラムしてください。それを表示するときはそれを実行しているコンピューターの文化や、プログラムで指定した文化で表示されます。

 

日本の文化を適用すれば平成や令和などの和暦をC#で扱うことも可能です。ToStringメソッドの第2引数には文化を指定できるので、ここで日本の和暦の文化を指定してみましょう。

ただ、このプログラムは入門講座としては少し高度なので、理屈の説明はここでは割愛します。

プログラムは次のようになります。

private void button1_Click(object sender, EventArgs e)
{
   //2020年6月27日を表すDateTimeオブジェクトを作成
    DateTime day = new DateTime(2020, 6, 27);

    //日本の文化を取得して、カレンダーに和暦を指定
    System.Globalization.CultureInfo culture = new System.Globalization.CultureInfo("ja-JP", true);
    culture.DateTimeFormat.Calendar = new System.Globalization.JapaneseCalendar();

    //02/06/27 (yyyyが西暦ではなく令和の年になる)
    MessageBox.Show(day.ToString("yyyy/MM/dd", culture));

    //令和2年6月27日(ggで「令和」)
    MessageBox.Show(day.ToString("ggy年M月d日", culture));
}

■リストF-1

日本の和暦の文化を適用した状態では yyyy は和暦の年になります。yy と書いても同じです。「平成」や「令和」などの元号の名称はggです。

なお、2019年を和暦で表示すると令和1年ではなく、令和元年になります。ちなみに、令和は2002年に.NETがリリースされてから世界で始めて発生した暦の変更でした。

 

8.日付についてその他

8-1.現在日付

DateTimeオブジェクトのNowプロパティ(読み方:Now = ナウ)は常にその時の日付を表しているので重宝します。使い方も簡単です。

次のプログラムは、現在の日付を表示します。

private void button1_Click(object sender, EventArgs e)
{
   DateTime day = DateTime.Now;
    MessageBox.Show(day.ToString());
}

■リストG-1

コンピュータが管理している現在の日付・時刻のことを「システム日付」、「システム時刻」とも呼びます。

 

8-2.時刻

「日付」という言葉はC#では時刻も含みます。ここまでの例では時刻は扱いませんでしたが、日付と同じようにDateTimeオブジェクトを生成して、書式指定を使って文字列にできます。

private void button1_Click(object sender, EventArgs e)
{
   //2020年6月27日13時14分15秒
    DateTime day = new DateTime(2020, 6, 20, 13, 14, 15);

    //13:14:15 と表示します。
    MessageBox.Show(day.ToString(@"HH\:mm\:ss"));
}

■リストG-2

 

9.メソッドとプロパティ

既にいくつか登場しましたが、文字列・数値・日付もメソッドとプロパティをもっています。

たとえば、文字列のLengthプロパティ (Length = レンクス)は文字列の文字数を表します。

private void button1_Click(object sender, EventArgs e)
{
   MessageBox.Show("こんにちは".Length.ToString());
}

■リストH-1

この例では、「5」と表示されます。Lengthは長さを表しているので値は数値型です。数値型はそのまま表示できないのでToStringを使って文字列型にしています。

 

ToUpperメソッド (ToUpper = トゥーアッパー)は英語の小文字をすべて英語の大文字に変換します。

private void button1_Click(object sender, EventArgs e)
{
   MessageBox.Show("Hello".ToUpper());
}

■リストH-2

この例では、「HELLO」と表示されます。

 

DateTimeにもさまざまな機能があります。

代表的な利用例をいくつか紹介します。

private void button1_Click(object sender, EventArgs e)
{
   DateTime testDay = new DateTime(2020, 6, 27);

    //次の日 → 2020/6/28
    DateTime nextDay = testDay.AddDays(1);
    MessageBox.Show(nextDay.ToString());

    //日付だけ → 27
    int day = testDay.Day;
    MessageBox.Show(day.ToString());

    //年だけ → 2020
    int year = testDay.Year;
    MessageBox.Show(year.ToString());

    //日付の引き算 7/1 までは 4日ある
    DateTime targetDay = new DateTime(2020, 7, 1);
    int diff = (targetDay - testDay).Days;
    MessageBox.Show(diff.ToString());
}

■リストH-3

最後の日付の引き算はまだ登場していない新しい文法で記述してみました。

日付の情報や操作にはいろいろあるので現段階では「こういったこともできる」という程度に覚えておいてください。日付を"2020/06/27"のような文字列してプログラムしてしまうと次の日を求めたり、年だけ抽出したりというような日付の処理は簡単にはできません。

 

他にも便利なメソッドやプロパティがいろいろとありますが、数が多すぎるので、必要に応じて説明していくことにします。

文字列型・DateTimeのメンバー(メソッドやプロパティなど)の一覧は下記で確認できます。現段階ではまだ知識がたりないので公式ドキュメントの解説の意味がわからないと思います。公式ドキュメントが読めるくらいの知識がたまれば独学でどんどんメンバーを使うことができるようになります。今後参考にしてください。

文字列型のメンバー

String クラス (System) | Microsoft Docs

 

DateTimeのメンバー

DateTime 構造体 (System) | Microsoft Docs

 

 

次の回では、Visual Studioでプログラムが実行される仕組みとエラーについて学びます。

C#入門講座 第7回 ビルド