年月日と時分秒の書式
Format関数などで日時の書式を表す場合に以下のようなコードを見ることがあります。
1 |
Format(Now, "yyyy/mm/dd hh:mm:ss") |
「mm」が年月日の「月」と時分秒の「分」の両方に使われています。
一見すると混乱しそうですが、VBAは文脈から自動的に月と分を区別してくれます。
これはVBAに限らず、一般的な年月日や時分秒の表し方で、どちらにも「m」を使うことがあるため、mmの左右の文字列の内容からVBAでも内部的に判定するためです。
具体的には、単体での”mm”は「月」として判断され、時間の”h”や秒の”s”と一緒に使用すると「分」とみなすようになっています。
正式な書式ルール:mは月、nは分
VBAで内部的にmを親切に解釈してくれますが、正式な書式のルールでは「m」は月を表し、分を表すのは「n」になります。
なお、mm、および、nnと2桁で書くと1桁値の場合に左側に0が付与されます。
そのため、正式な年月日+時分秒の書式は
「”yyyy/mm/dd hh:nn:ss”」
になります。
ところが一般的には
「”yyyy/mm/dd hh:mm:ss”」
の方が利用されることが多いです。
Format関数を使うと以下はどちらも同じ時刻を出力します。
1 2 3 4 5 6 7 8 9 10 11 12 |
Sub FormatNowTest() Dim fmt Dim dt dt = Now fmt = Format(dt, "yyyy/mm/dd hh:mm:ss") Debug.Print fmt fmt = Format(dt, "yyyy/mm/dd hh:nn:ss") Debug.Print fmt End Sub |
注意が必要なケース
上にも書いたとおり、”mm”は単体では「月」として判断されます。
一番問題になるのが、「時分秒」の「分秒」を表したいときです。”hh:mm:ss”の”hh”を除いて”mm:ss”とすると、「分秒」ではなく「月秒」として判断されます。
「分」だけを取得する場合は”mm”単体ではなく、”nn”を使用します。
以下はそれらの注意するパターンです。
1 2 3 4 5 6 7 8 9 |
Sub mmssnnssTest() Dim dt As Date dt = CDate("2025/10/13 12:34:56") Debug.Print Format(dt, "mm") '// 10「月」として解釈される Debug.Print Format(dt, "nn") '// 34「分」として解釈される Debug.Print Format(dt, "mm:ss") '// ★10:56「月:秒」として解釈されてしまう! Debug.Print Format(dt, "nn:ss") '// 34:56「分:秒」 End Sub |
hh:mm:ssとhh:nn:ssの処理速度の違い
もしかしたらhh:mm:ssとhh:nn:ssでは処理速度に違いがあるのかも、と思って調べてみました。
結果、差はありませんでした。
hh:mm:ssとhh:nn:ssのFormatを500万回ずつ実行してみましたが、0.01秒の差しかなく、誤差の範囲と思います。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 |
Sub FormatNowTest2() Dim fmt Dim dt Dim i Dim iMax dt = Now iMax = 5000000 Debug.Print Timer For i = 0 To iMax fmt = Format(dt, "yyyy/mm/dd hh:mm:ss") Next Debug.Print Timer For i = 0 To iMax fmt = Format(dt, "yyyy/mm/dd hh:nn:ss") Next Debug.Print Timer End Sub |
実行結果
61973.04
61977.29 (前回から4.25)
61981.55 (前回から4.26)
結論。mmとnnどっちでもいいけど、分だけのときはnn
結論。
hh:mm:ssとhh:nn:ss、どっちでもいいです。
私自身、hh:mm:ssで書いてますし。
正式な書式を使いたい場合は、分には”nn”を使ってください。
迷う場合や日時書式が厳密に必要な場合は、以下のように定数を使ってFormat関数を使うこともオススメします。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
Const MONTH_FORMAT As String = "mm" '// 月(2桁) Const MINUTES_FORMAT As String = "nn" '// 分(2桁) Const DATE_FORMAT As String = "yyyy/mm/dd" '// 年月日 Const TIME_FORMAT As String = "hh:nn:ss" '// 時分秒 Const DATETIME_FORMAT As String = "yyyy/mm/dd hh:nn:ss" '// 年月日時分秒 Sub mmnnTest() Dim dt As Date dt = CDate("2025/10/13 12:34:56") Debug.Print Format(dt, MONTH_FORMAT) '// 月:10 Debug.Print Format(dt, MINUTES_FORMAT) '// 分:34 Debug.Print Format(dt, DATE_FORMAT) '// 年月日:2025/10/13 Debug.Print Format(dt, TIME_FORMAT) '// 時分秒:12:34:56 Debug.Print Format(dt, DATETIME_FORMAT) '// 年月日時分秒:2025/10/13 12:34:56 End Sub |