VB.NETで日付と時間を扱う方法!(DateTime)

VB.NET

VB.NETで日付と時刻を扱うことは、アプリケーション開発において非常に基本的ながら重要なタスクです。
ユーザーからの入力処理、ログの記録、スケジュール管理、データのフィルタリングなど、様々な場面で日付と時刻の操作が必要になります。

VB.NETでは、System.DateTime 構造体が日付と時刻の情報を表現するための主要な手段として提供されています。
この記事では、DateTime 構造体の基本的な使い方、オブジェクトの作成、書式設定、文字列からの変換、計算方法、そして関連する注意点について解説します。

DateTimeの基本

System.DateTimeは、日付(年、月、日)と時刻(時、分、秒、ミリ秒)の単一の時点を表す値型(構造体)です。
内部的には、西暦1年1月1日午前0時からの経過ティック数(100ナノ秒単位)として日付と時刻を保持しています。

DateTimeの使い方

DateTimeを実際に使って、動作を確認していきます。

1. 現在の日付と時刻を取得する

現在の日付と時刻を取得してみます。

  • DateTime.Now: 現在のローカルシステムの日付と時刻を取得します。
  • DateTime.Today: 現在のローカルシステムの日付のみを取得します(時刻は午前0時0分0秒になります)。
  • DateTime.UtcNow: 現在のUTC(協定世界時)の日付と時刻を取得します。タイムゾーンの影響を受けないため、国際的なアプリケーションやサーバー間の時刻同期によく使用されます。
Module CurrentDateTimeExample
    Sub Main()
        Dim nowDateTime As DateTime = DateTime.Now
        Dim todayDate As DateTime = DateTime.Today
        Dim utcNowDateTime As DateTime = DateTime.UtcNow

        Console.WriteLine($"現在のローカル日時: {nowDateTime}")
        Console.WriteLine($"今日の日付: {todayDate}")
        Console.WriteLine($"現在のUTC日時: {utcNowDateTime}")
    End Sub
End Module

DateTime.NowDateTime.TodayDateTime.UtcNowを使って、現在の日時、日付、UTC日時を取得しました。
実際に実行すると、下記のように出力されました。

現在の日付と時刻が取得できました。

現在のローカル日時: 2025/07/17 22:13:45
今日の日付: 2025/07/17 0:00:00
現在のUTC日時: 2025/07/17 13:13:45

2. 特定の日付と時刻を作成する (コンストラクタ)

DateTimeには、様々な引数を受け取る複数のコンストラクタが用意されています。

  • 日付のみ: New DateTime(year, month, day)
  • 日付と時刻: New DateTime(year, month, day, hour, minute, second)
  • 詳細な時刻: New DateTime(year, month, day, hour, minute, second, millisecond)
Module SpecificDateTimeExample
    Sub Main()
        ' 2025年7月15日
        Dim specificDate As New DateTime(2025, 7, 15)
        Console.WriteLine($"特定の日付: {specificDate}")

        ' 2025年7月15日 14時30分0秒
        Dim specificDateTime As New DateTime(2025, 7, 15, 14, 30, 0)
        Console.WriteLine($"特定の日時: {specificDateTime}")

        ' 2025年7月15日 14時30分0秒500ミリ秒
        Dim specificDateTimeWithMs As New DateTime(2025, 7, 15, 14, 30, 0, 500)
        Console.WriteLine($"ミリ秒を含む日時: {specificDateTimeWithMs.ToString("yyyy/MM/dd HH:mm:ss.fff")}")
    End Sub
End Module

最初にNew DateTimeDateTimeを作成するときに、年月日を指定して作成しています。
そして、次に年月日時分秒を指定して作成しています。
最後に、ミリ秒まで指定して作成しています。

それぞれ、出力すると、下記のように指定日・時刻で出力されました。
ミリ秒はToStringメソッドで、フォーマットを指定して出力する必要があります。

特定の日付: 2025/07/15 0:00:00
特定の日時: 2025/07/15 14:30:00
ミリ秒を含む日時: 2025/07/15 14:30:00.500

日付と時刻の書式設定

DateTimeオブジェクトを文字列に変換するには、ToStringメソッドを使用します。
ToStringには、標準書式指定子やカスタム書式指定子を渡すことで、様々な形式で日付と時刻を表示できます。

1. 標準書式指定子

よく使われる標準書式指定子には以下のようなものがあります。

  • "d": 短い日付形式 (例: 2025/07/15)
  • "D": 年月日の日付形式 (例: 2025年7月15日)
  • "t": 短い時刻形式 (例: 14:30)
  • "T": 秒を含んだ時刻形式 (例: 14:30:00)
  • "f": 短い日付と時刻 (例: 2025年7月15日 14:30)
  • "F": 長い日付と時刻 (例: 2025年7月15日 14:30:00)
  • "g": 短い日付と短い時刻 (例: 2025/07/15 14:30)
  • "G": 短い日付と長い時刻 (例: 2025/07/15 14:30:00)
  • "s": ISO 8601 形式 (yyyy-MM-ddTHH:mm:ss)
Module FormatDateTimeExample
    Sub Main()
        Dim dt As New DateTime(2025, 7, 15, 14, 30, 5)

        Console.WriteLine($"短い日付: {dt.ToString("d")}")
        Console.WriteLine($"長い日付: {dt.ToString("D")}")
        Console.WriteLine($"短い時刻: {dt.ToString("t")}")
        Console.WriteLine($"長い時刻: {dt.ToString("T")}")
        Console.WriteLine($"短い日付と時刻: {dt.ToString("f")}")
        Console.WriteLine($"長い日付と時刻: {dt.ToString("F")}")
        Console.WriteLine($"ISO 8601: {dt.ToString("s")}")
    End Sub
End Module

2025-07-15 14:30:05」を指定してDateTimeを作成しました。
それぞれの形式で出力すると、下記のように出力されました。

短い日付: 2025/07/15
長い日付: 2025年7月15日
短い時刻: 14:30
長い時刻: 14:30:05
短い日付と時刻: 2025年7月15日 14:30
長い日付と時刻: 2025年7月15日 14:30:05
ISO 8601: 2025-07-15T14:30:05

指定したフォーマットで出力されたことが確認できます。

2. カスタム書式指定子

より柔軟な書式設定を行うには、カスタム書式指定子を使用します。

  • yyyy: 年 (4桁)
  • MM: 月 (2桁、0埋め)
  • dd: 日 (2桁、0埋め)
  • HH: 時 (24時間形式、2桁、0埋め)
  • hh: 時 (12時間形式、2桁、0埋め)
  • mm: 分 (2桁、0埋め)
  • ss: 秒 (2桁、0埋め)
  • fff: ミリ秒 (3桁、0埋め)
  • tt: 午前/午後 (AM/PM)
  • /, :: 日付や時刻の区切り文字
  • "文字列": リテラル文字列
Module CustomFormatExample
    Sub Main()
        Dim dt As New DateTime(2025, 7, 15, 9, 5, 30)

        Console.WriteLine($"カスタム1: {dt.ToString("yyyy年MM月dd日 HH時mm分ss秒")}")
        Console.WriteLine($"カスタム2: {dt.ToString("MM/dd/yyyy hh:mm tt")}")
        Console.WriteLine($"カスタム3: {dt.ToString("yyyy-MM-dd")}")
        Console.WriteLine($"カスタム4: {dt.ToString("HH:mm:ss.fff")}")
    End Sub
End Module

それぞれ、下記のように出力されました。
指定した書式で出力されることが確認できました。

カスタム1: 2025年07月15日 09時05分30秒
カスタム2: 07/15/2025 09:05 午前
カスタム3: 2025-07-15
カスタム4: 09:05:30.000

文字列からDateTimeへの変換

文字列形式の日付と時刻をDateTimeオブジェクトに変換するには、ParseTryParseParseExact メソッドを使用します。

1. DateTime.Parse

様々な日付/時刻文字列を自動的に解析しようとします。解析に失敗すると例外をスローします。

Module ParseExample
    Sub Main()
        Dim dateString1 As String = "2025/07/15"
        Dim dateString2 As String = "July 15, 2025 14:30:00"

        Try
            Dim dt1 As DateTime = DateTime.Parse(dateString1)
            Console.WriteLine($"'{dateString1}' を解析: {dt1}")

            Dim dt2 As DateTime = DateTime.Parse(dateString2)
            Console.WriteLine($"'{dateString2}' を解析: {dt2}")

            Dim invalidDateString As String = "Invalid Date"
            Dim dtInvalid As DateTime = DateTime.Parse(invalidDateString) ' ここで例外が発生
            Console.WriteLine($"'{invalidDateString}' を解析: {dtInvalid}")

        Catch ex As FormatException
            Console.WriteLine($"エラー: 日付文字列の形式が正しくありません。{ex.Message}")
        End Try
    End Sub
End Module

DateTime.Parseメソッドを使って、異なる形式の文字列をDateTimeオブジェクトに変換しようとしています。

“2025/07/15″や”July 15, 2025 14:30:00″のような一般的な日付時刻形式は自動的に解析されます。
しかし、”Invalid Date”のようにDateTimeとして認識できない文字列を渡すと、FormatExceptionという例外が発生します。
そのため、Parseメソッドを使用する際は、必ずTry...Catchブロックで例外処理を行う必要があります。

実行すると、下記のように最後のInvalid Dateは解析に失敗して、エラーがでていることが確認できます。

'2025/07/15' を解析: 2025/07/15 0:00:00
'July 15, 2025 14:30:00' を解析: 2025/07/15 14:30:00
エラー: 日付文字列の形式が正しくありません。The string 'Invalid Date' was not recognized as a valid DateTime. There is an unknown word starting at index '0'.

2. DateTime.TryParse

解析に成功したかどうかを示すブール値を返し、解析された第DateTimeオブジェクトは第2引数のパラメータに格納されます。
解析に失敗しても例外をスローしないため、安全な変換に推奨されます。

Module TryParseExample
    Sub Main()
        Dim dateString1 As String = "2025-07-15 10:30"
        Dim dateString2 As String = "Not a date"
        Dim parsedDateTime As DateTime

        If DateTime.TryParse(dateString1, parsedDateTime) Then
            Console.WriteLine($"'{dateString1}' を正常に解析: {parsedDateTime}")
        Else
            Console.WriteLine($"'{dateString1}' の解析に失敗しました。")
        End If

        If DateTime.TryParse(dateString2, parsedDateTime) Then
            Console.WriteLine($"'{dateString2}' を正常に解析: {parsedDateTime}")
        Else
            Console.WriteLine($"'{dateString2}' の解析に失敗しました。") ' 出力される
        End If
    End Sub
End Module

DateTime.TryParseメソッドを使って文字列をDateTimeに変換しています。

TryParseメソッドは、変換が成功した場合はTrueを返し、変換されたDateTimeオブジェクトをparsedDateTime変数に格納します。
変換が失敗した場合はFalseを返し、例外は発生しません。

これにより、無効な日付文字列が入力された場合でもアプリケーションがクラッシュすることなく、安全に処理を継続できます。
ユーザーからの入力など、形式が不確実な文字列を変換する際に非常に推奨される方法です。

コードを実行すると、dateString2は解析に失敗することが確認できます。

'2025-07-15 10:30' を正常に解析: 2025/07/15 10:30:00
'Not a date' の解析に失敗しました。

3. DateTime.ParseExact

厳密に指定された書式パターンに一致する場合のみ解析を行います。
これにより、曖昧な日付文字列の解析を防ぎ、より堅牢なコードを書くことができます。

Module ParseExactExample
    Sub Main()
        Dim dateString As String = "2025/07/15 14:30:00"
        Dim format As String = "yyyy/MM/dd HH:mm:ss"
        Dim parsedDateTime As DateTime

        If DateTime.TryParseExact(dateString, format, Nothing, System.Globalization.DateTimeStyles.None, parsedDateTime) Then
            Console.WriteLine($"'{dateString}' を書式 '{format}' で正常に解析: {parsedDateTime}")
        Else
            Console.WriteLine($"'{dateString}' を書式 '{format}' で解析できませんでした。")
        End If

        Dim wrongFormatString As String = "2025-07-15 14:30:00" ' フォーマットが異なる
        If DateTime.TryParseExact(wrongFormatString, format, Nothing, System.Globalization.DateTimeStyles.None, parsedDateTime) Then
            Console.WriteLine($"'{wrongFormatString}' を書式 '{format}' で正常に解析: {parsedDateTime}")
        Else
            Console.WriteLine($"'{wrongFormatString}' を書式 '{format}' で解析できませんでした。") ' 出力される
        End If
    End Sub
End Module

DateTime.TryParseExactメソッドを使って文字列を特定の厳密な書式で解析しています。

“2025/07/15 14:30:00″は”yyyy/MM/dd HH:mm:ss”というformat文字列に完全に一致するため、正常に解析されます。
しかし、”2025-07-15 14:30:00″のように、わずかに形式が異なる文字列を同じフォーマットで解析しようとすると、TryParseExactFalseを返し、解析に失敗します。

これは、入力される日付文字列の形式が常に一定であると分かっている場合に、誤った形式の入力を防ぐために非常に有効です。
コードを実行すると、フォーマットが異なるため2番目のTryParseExactは、下記のように失敗します。

'2025/07/15 14:30:00' を書式 'yyyy/MM/dd HH:mm:ss' で正常に解析: 2025/07/15 14:30:00
'2025-07-15 14:30:00' を書式 'yyyy/MM/dd HH:mm:ss' で解析できませんでした。

日付と時刻の計算

DateTimeオブジェクトは、日付や時刻の加算・減算を行うための様々なメソッドを提供します。

1. 加算 (Add メソッド群)

  • AddYears(value As Integer)
  • AddMonths(value As Integer)
  • AddDays(value As Double)
  • AddHours(value As Double)
  • AddMinutes(value As Double)
  • AddSeconds(value As Double)
  • AddMilliseconds(value As Double)
  • AddTicks(value As Long)

これらのメソッドは、元の DateTime オブジェクトを変更せず、新しい DateTime オブジェクトを返します。

Module AddDateTimeExample
    Sub Main()
        Dim dt As New DateTime(2025, 7, 15, 10, 0, 0)

        Dim nextYear As DateTime = dt.AddYears(1)
        Console.WriteLine($"1年後: {nextYear}")

        Dim nextMonth As DateTime = dt.AddMonths(1)
        Console.WriteLine($"1ヶ月後: {nextMonth}")

        Dim threeDaysLater As DateTime = dt.AddDays(3)
        Console.WriteLine($"3日後: {threeDaysLater}")

        Dim twoHoursLater As DateTime = dt.AddHours(2)
        Console.WriteLine($"2時間後: {twoHoursLater}")

        Dim tenMinutesAgo As DateTime = dt.AddMinutes(-10) ' 負の数を指定して減算も可能
        Console.WriteLine($"10分前: {tenMinutesAgo}")
    End Sub
End Module

dtという基準のDateTimeオブジェクトに対して、様々なAddメソッドを使って期間を加算しています。

AddYears(1)は1年後、AddMonths(1)は1ヶ月後、AddDays(3)は3日後の日付を計算します。
AddHours(2)は2時間後、AddMinutes(-10)は負の数を指定することで10分前の時刻を計算しています。

これらのメソッドは、元のdtオブジェクトを変更せず、常に新しいDateTimeオブジェクトを返すため、元の値に影響を与えずに計算結果を利用できます。
実行結果は下記のとおりです。

1年後: 2026/07/15 10:00:00
1ヶ月後: 2025/08/15 10:00:00
3日後: 2025/07/18 10:00:00
2時間後: 2025/07/15 12:00:00
10分前: 2025/07/15 9:50:00

2. 減算 (Subtract メソッド)

Subtract メソッドには2つのオーバーロードがあります。

  • Subtract(value As TimeSpan): DateTime から TimeSpan を減算し、新しい DateTime を返します。
  • Subtract(value As DateTime): 2つの DateTime オブジェクトの差を計算し、TimeSpan オブジェクトを返します。
Module SubtractDateTimeExample
    Sub Main()
        Dim dt1 As New DateTime(2025, 7, 20, 10, 0, 0)
        Dim dt2 As New DateTime(2025, 7, 15, 8, 30, 0)

        ' DateTime から TimeSpan を減算
        Dim fiveDays As New TimeSpan(5, 0, 0, 0) ' 5日間のTimeSpan
        Dim fiveDaysAgo As DateTime = dt1.Subtract(fiveDays)
        Console.WriteLine($"5日前: {fiveDaysAgo}")

        ' 2つのDateTimeの差を計算し、TimeSpan を取得
        Dim difference As TimeSpan = dt1.Subtract(dt2)
        Console.WriteLine($"日時間の差: {difference}")
        Console.WriteLine($"差の合計日数: {difference.TotalDays}")
        Console.WriteLine($"差の合計時間: {difference.TotalHours}")
    End Sub
End Module

Subtractメソッドの2つの使い方を示しています。
最初の部分では、dt1からfiveDaysというTimeSpanオブジェクト(5日間)を減算し、5日前の日付fiveDaysAgoを取得しています。

次に、dt1とdt2という2つのDateTimeオブジェクトの差を計算し、その結果をTimeSpanオブジェクトとしてdifferenceに格納しています。TimeSpanオブジェクトからは、TotalDaysTotalHours`などのプロパティを使って、期間の合計日や合計時間などを取得できます。
実行結果は下記のとおりです。

5日前: 2025/07/15 10:00:00
日時間の差: 5.01:30:00
差の合計日数: 5.0625
差の合計時間: 121.5

TimeSpanで期間を扱う

System.TimeSpan構造体は、時間の間隔や期間を表します。
日付計算の結果として得られたり、特定の期間を定義するために使用されます。

  • New TimeSpan(days, hours, minutes, seconds)
  • New TimeSpan(hours, minutes, seconds)
  • TimeSpan.FromDays(), TimeSpan.FromHours(), TimeSpan.FromMinutes() など
Module TimeSpanExample
    Sub Main()
        ' 2日と12時間の期間
        Dim duration1 As New TimeSpan(2, 12, 0, 0)
        Console.WriteLine($"期間1: {duration1}")

        ' 30分間の期間
        Dim duration2 As TimeSpan = TimeSpan.FromMinutes(30)
        Console.WriteLine($"期間2: {duration2}")

        ' 日時に期間を加算
        Dim startDateTime As DateTime = DateTime.Now
        Dim endDateTime As DateTime = startDateTime.Add(duration1)
        Console.WriteLine($"開始日時: {startDateTime}")
        Console.WriteLine($"終了日時 (期間1を加算): {endDateTime}")
    End Sub
End Module

TimeSpanを使って時間の間隔を定義しています。

duration1はコンストラクタに日、時、分、秒を渡して「2日と12時間」の期間を作成しています。
duration2TimeSpan.FromMinutes(30)というファクトリメソッドを使って「30分間」の期間をより直感的に作成しています。

最後にstartDateTime.Add(duration1)のように、DateTimeオブジェクトのAddメソッドにTimeSpanオブジェクトを渡すことで、特定の期間を加算した新しいDateTimeオブジェクトを取得できることを示しています。
実行結果は下記のとおりです。

期間1: 2.12:00:00
期間2: 00:30:00
開始日時: 2025/07/18 17:34:07
終了日時 (期間1を加算): 2025/07/21 5:34:07

DateTime の主要プロパティ

DateTime オブジェクトは、日付や時刻の各要素にアクセスするための便利なプロパティを提供します。

  • Year, Month, Day
  • Hour, Minute, Second, Millisecond
  • DayOfWeek (曜日、DayOfWeek 列挙型を返す)
  • DayOfYear (年の何日目か)
  • Date (時刻部分が00:00:00の DateTime オブジェクトを返す)
  • TimeOfDay (TimeSpan オブジェクトとして時刻部分を返す)
Module DateTimePropertiesExample
    Sub Main()
        Dim dt As New DateTime(2025, 7, 15, 14, 30, 45, 123)

        Console.WriteLine($"年: {dt.Year}")
        Console.WriteLine($"月: {dt.Month}")
        Console.WriteLine($"日: {dt.Day}")
        Console.WriteLine($"時: {dt.Hour}")
        Console.WriteLine($"分: {dt.Minute}")
        Console.WriteLine($"秒: {dt.Second}")
        Console.WriteLine($"ミリ秒: {dt.Millisecond}")
        Console.WriteLine($"曜日: {dt.DayOfWeek}") ' 例: Tuesday
        Console.WriteLine($"年の何日目: {dt.DayOfYear}")
        Console.WriteLine($"日付部分のみ: {dt.Date}")
        Console.WriteLine($"時刻部分のみ (TimeSpan): {dt.TimeOfDay}")
    End Sub
End Module

dtというDateTimeオブジェクトが持つ様々なプロパティにアクセスし、その値を出力しています。

Year、Month、Day、Hour、Minute、Second、Millisecondは、それぞれ日付時刻の各要素を数値で取得します。
DayOfWeekは曜日を、DayOfYearは年の何日目かを示します。

Dateプロパティは時刻部分を午前0時0分0秒に設定した新しいDateTimeオブジェクトを返してます。
TimeOfDayプロパティは時刻部分をTimeSpanオブジェクトとして返します。

実行結果は、下記のとおりです。

年: 2025
月: 7
日: 15
時: 14
分: 30
秒: 45
ミリ秒: 123
曜日: Tuesday
年の何日目: 196
日付部分のみ: 2025/07/15 0:00:00
時刻部分のみ (TimeSpan): 14:30:45.1230000

DateTimeを扱う際の注意点

DateTimeを扱う際の注意点です。

タイムゾーン

DateTime.Now はローカルタイムゾーンに依存します。
国際的なアプリケーションや異なるタイムゾーンのユーザーを扱う場合は、DateTime.UtcNow を使用し、必要に応じてタイムゾーン変換を行う TimeZoneInfo クラスの利用を検討してください。

カルチャの影響

ToStringParseメソッドは、デフォルトで現在のシステムカルチャ(地域設定)に依存します。
特定の書式やカルチャで処理したい場合は、IFormatProvider (例: System.Globalization.CultureInfo) を引数として渡すことで明示的に指定できます。

Nothing(Null) の扱い

DateTime は値型なので、Nothing を直接代入することはできません(デフォルト値は 0001/01/01 0:00:00
Null 可能な日付を扱いたい場合は、Nullable(Of DateTime) または DateTime? を使用します。

Dim nullableDate As DateTime? = Nothing ' Null許容型
If nullableDate.HasValue Then
    Console.WriteLine(nullableDate.Value)
Else
    Console.WriteLine("日付は設定されていません。")
End If

まとめ

VB.NETにおけるDateTimeは、日付と時刻を正確かつ柔軟に扱うための強力なツールです。
現在の日時取得、特定の日時の作成、多様な書式設定、文字列との相互変換、そして日付/時刻の計算といった基本的な操作は、ほとんどのアプリケーションで必要とされます。

特に、TryParseによる安全な変換や、タイムゾーン、カルチャの考慮、Nullable(Of DateTime) の使用など、注意すべき点を理解することで、より堅牢で信頼性の高い日付/時刻処理を実装できるようになります。

コメント