早く流れる川で

雑に書き留めた何か

C#, DateTimeのあれこれ

はじめに

久々に C# に触れている。
DateTime の使い方がおぼろげ?なので備忘録として残す。

開発環境

プロジェクト

  • コンソールアプリ
    • .NET Core 3.1
    • プロジェクト名は TryDateTime

あれこれ

  • 初期値
  • 初期化
  • AddXX() を用いた増減
  • 実行時の日時が知りたい
  • 月末を得たい
  • 日時同士の計算(差引のみ)
  • 表示形式の変更
  • 差引した日時の合計

初期値

using System;
using System.Diagnostics;

namespace TryDateTime
{
    class Program
    {
        static void Main(string[] args)
        {
            Sample1();
        }

        public static void Sample1()
        {
            var datetime = new DateTime();

            /*
                実行結果
                0001/01/01 0:00:00
            */
            Debug.WriteLine(datetime);
        }
    }
}
  • これ以降は SampleN() 内のコードを載せる
    • 1 <= N && N <= ...
  • System.DiagnosticsDebug.WriteLine() を使いたかったから追加した
    • 実行結果をコピペしたい

初期化

        public static void Sample2()
        {
            var datetime1 = new DateTime(1, 2, 3);

            // 0001/02/03 0:00:00
            Debug.WriteLine(datetime1);

            var datetime2 = new DateTime(1, 2, 3, 4, 5, 6);

            // 0001/02/03 4:05:06
            Debug.WriteLine(datetime2);
        }
  • 年、月、日、時、分、秒を指定する
  • ミリ秒も指定できる
  • ticks やら DateTimeKind を使って初期化もできる
  • 個人的には載せたやつばかり使っている

AddXX() を用いた増減

        public static void Sample3()
        {
            var datetime = new DateTime();
            datetime = datetime.AddYears(1);

            // 0002/01/01 0:00:00
            Debug.WriteLine(datetime);

            datetime = datetime.AddMonths(2);

            // 0002/03/01 0:00:00
            Debug.WriteLine(datetime);

            datetime = datetime.AddDays(3);

            // 0002/03/04 0:00:00
            Debug.WriteLine(datetime);

            datetime = datetime.AddHours(4);

            // 0002/03/04 4:00:00
            Debug.WriteLine(datetime);

            datetime = datetime.AddMinutes(5);

            // 0002/03/04 4:05:00
            Debug.WriteLine(datetime);

            datetime = datetime.AddSeconds(6);

            // 0002/03/04 4:05:06
            Debug.WriteLine(datetime);

            datetime = datetime
                .AddYears(-1)
                .AddMonths(-2)
                .AddDays(-3)
                .AddHours(-4)
                .AddMinutes(-5)
                .AddSeconds(-6);

            // 0001/01/01 0:00:00
            Debug.WriteLine(datetime);
        }

実行時の日時が知りたい

        public static void Sample4()
        {
            var datetime = DateTime.Now;

            // 2022/04/21 23:59:30
            Debug.WriteLine(datetime);
        }
  • よい子は寝ましょう

月末を得たい

  • ↓駄目な例です
        public static void Sample5()
        {
            var now         = DateTime.Now;
            var last_day    = new DateTime(now.Year, now.Month + 1, 1).AddDays(-1);

            // 2022/04/30 0:00:00
            Debug.WriteLine(last_day);
        }
  • ↑駄目な例です
  • now が12月だと次の例外が発生する
System.ArgumentOutOfRangeException: 'Year, Month, and Day parameters describe an un-representable DateTime.'

かなり意訳すると13月って何?無理!

        public static void Sample5A()
        {
            var now = new DateTime(2022, 12, 12);
            var last_day = new DateTime(now.Year, now.Month, 1).AddMonths(1).AddDays(-1);

            // 2022/12/31 0:00:00
            Debug.WriteLine(last_day);
        }

これなら大丈夫、これを書きたかった。
12月に + 1 したらアウトじゃないか?って思ったら案の定例外だった。

日時同士の計算(差引のみ)

        public static void Sample6()
        {
            var datetime_a = new DateTime(2022, 4, 21, 9, 0, 0);
            var datetime_b = new DateTime(2022, 4, 21, 18, 0, 0);
            var result = datetime_b - datetime_a;

            // 09:00:00
            Debug.WriteLine(result);
        }
  • 結果は TimeSpan 型

表示形式の変更

        public static void Sample7()
        {
            var now = DateTime.Now;

            // 2022-04-22 01:28:49
            Debug.WriteLine(now.ToString("yyyy-MM-dd HH:mm:ss"));

            // 2022年04月22日(金) 01時28分49秒
            Debug.WriteLine(now.ToString("yyyy年MM月dd日(ddd) HH時mm分ss秒"));
        }

差引した日時の合計

        public static void Sample8()
        {
            var times = new List<TimeSpan>
            {
                new DateTime(2022, 4, 1, 18, 0, 0) - new DateTime(2022, 4, 1, 9, 0, 0),
                new DateTime(2022, 4, 2, 18, 0, 0) - new DateTime(2022, 4, 2, 9, 0, 0),
                new DateTime(2022, 4, 3, 18, 0, 0) - new DateTime(2022, 4, 3, 9, 0, 0)
            };

            var result = new TimeSpan(times.Select(x => x.Ticks).Sum());

            // 1.03:00:00
            Debug.WriteLine(result);
        }
  • 結果は27時間 = 1日と3時間
  • Ticks は long 型
    • あれ?最大値を超えたら例外が発生するのでは?
    • long.MaxValue = 9223372036854775807
    • 1時間 = 36000000000
    • long.MaxValue / 36000000000 = 256204778 hours
    • 256204778 hours / 24 hous = 10675199.0833... days
    • 10675199 days / 365 days = 29247.12054794521 years
    • 29247年の集計ってなかなか無さそう
  • List は System.Collections.Generic
  • Select() や Sum() は System.Ling

所感

そんなに忘れていなかった。型があるのは良い。
月末を得たいで例外を見つけて何だか書く気になった。

その他

やっぱ、プログラミングは楽しいなぁ…
今はプログラミングとは無関係の職だけど復帰したい。
前回の記事から7か月後ってマジか…マジか…