文字列から日付(Date型)への変換
このページでは日付形式の文字列から日付(Date型)への変換する方法を解説します。
日付形式の文字列には「yyyy/mm/dd」形式や「yyyymmdd」形式など表現方法がいくつかありますが、そのままDate型に変換できるものとそうでないものがあります。
この記事では、主に次のような変換方法について紹介します。
- yyyy/mm/dd 形式の文字列を直接CDate関数で変換する方法
- yyyymmdd形式の文字列を加工してから変換する方法
- 変換可否を判定するIsDate関数の注意点と補完方法
- 変換時のエラー対応とロケール(国や言語の違い)の影響
なお、文字列から日付に変換するのとは逆の、日付から文字列への変換は「VBAで日付(Date型)から文字列に変換する」をご参照ください。
【パターン1】スラッシュ付きのyyyy/mm/dd形式はそのままCDate関数で変換する
スラッシュ区切りの年月日の文字列はそのままCDate関数でDate型に変換できます。
1 2 3 4 5 6 7 8 |
Sub StringToDate1() Dim s As String Dim dt As Date s = "2018/03/29" dt = CDate(s) End Subぽ |
ポイント
- PCのロケール(国や言語の違い)設定によっては、yyyy-dd-mmのような順序の違いがあります。
- 日付として不正な文字列(例:”2018/13/40″)を渡すとエラーが発生します。
【パターン2】yyyymmdd形式はyyyy/mm/ddに加工してからCDate関数で変換する
「20180329」のように8文字の数字で日付を表す文字列は、そのままではDate型には変換できません。
そのため、文字列の年・月・日に分解して「yyyy/mm/dd」形式に変換してからCDate関数で変換する必要があります。
次の2通りの方法があります。
方法1:Format関数を使う
1 2 3 4 5 6 7 8 9 |
Sub StringToDate1() Dim s As String Dim dt As Date s = "20180329" dt = CDate(Format(s, "####/##/##")) '// #は数字1文字を表す Debug.Pring dt '// 2018/03/29 と出力 End Sub |
方法2:Mid関数で年・月・日を切り出す
1 2 3 4 5 6 7 8 9 |
Sub StringToDate1() Dim s As String Dim dt As Date s = "20180329" dt = CDate(Mid(s, 1, 4) & "/" & Mid(s, 5, 2) & "/" & Mid(s, 7, 2)) Debug.Print dt '// 2018/03/19 と出力 End Sub |
どちらの方法でも同じ結果になります。どちらを使ってもOKです。
ポイント
- Format方式は桁数が崩れるとエラーになる恐れがあります。
- Midでの変換は、日付文字列がyyyymmddと8文字であることが固定されていれば使いやすいです。
IsDate関数の拡張関数
VBAには、文字列が日付に変換可能かどうかを判定するIsDate関数があります。
1 2 3 4 5 |
Sub CheckDate() Debug.Print IsDate("2018/03/29") '// True Debug.Print IsDate("20180329") '// False Debug.Print IsDate("0002017/08/31") '// True(注意!実際にはFalseで返してほしい) End Sub |
このコードのように、「2018/03/29」は True を返しますが、「20180329」は False になります。また、「0002017/08/31」のような変な文字列でも True を返すことがあり、意図しない判定をする場合があります。
個人的にはちょっと不便だと感じます。
このような不便さを解消するために、独自の判定ロジックを備えた関数を「8桁日付やスラッシュ編集日付用のIsDate関数」にて紹介しています。併せてごらんください。
実務で役立つエラー対策とロケール(国や言語の違い)の注意点
エラーを回避することを重視すると以下のような関数で回避することも可能です。
やっているのは、8文字数字であるか? IsDate関数で変換できるか?を判定して、OKであれば日付に変換し、NGであればエラーを返す仕組みです。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 |
Function SafeStringToDate(a_sDate As String) As Variant On Error GoTo ErrHandler Dim s As String s = a_sDate '// 引数文字列が数字8文字の場合 If Len(s) = 8 And IsNumeric(s) Then '// yyyy/mm/dd に変換 s = Mid(s, 1, 4) & "/" & Mid(s, 5, 2) & "/" & Mid(s, 7, 2) End If '// 日付変換できる場合 If IsDate(s) Then '// CDateでの変換後日付を返す SafeStringToDate = CDate(s) Else '// 日付変換できない場合はエラーとして返す SafeStringToDate = CVErr(xlErrValue) End If Exit Function ErrHandler: '// 例外発生時はエラーとして返す SafeStringToDate = CVErr(xlErrValue) End Function |
使い方
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 |
Sub SafeStringToDateTest() Dim s s = SafeStringToDate("20250805") Debug.Print s '// 2025/08/05 s = SafeStringToDate("2025085") Debug.Print s '// エラー 2015 s = SafeStringToDate("2025805") Debug.Print s '// エラー 2015 s = SafeStringToDate("250805") Debug.Print s '// エラー 2015 s = SafeStringToDate("202508050") Debug.Print s '// エラー 2015 s = SafeStringToDate("20250835") Debug.Print s '// エラー 2015 End Sub |
ポイント
- 数値8桁なら自動で変換します。
- IsDate で安全確認後に CDateで日付に変換します。
- エラーは CVErr(xlErrValue) で返します。このエラーはExcelシートでもエラーとして扱えます。
まとめ
- yyyy/mm/dd → そのまま CDateを使ってください。
- yyyymmdd → 加工して CDateを行う必要があります。
- IsDate → 判定に注意、必要なら拡張関数「8桁日付やスラッシュ編集日付用のIsDate関数」を使用してください。
- 国や言語が異なる場合ではロケールとエラー処理を意識する必要があります。