文章目录

VBA 日期处理:Date、Now、Format

发布于 2026-04-05 03:47:13 · 浏览 13 次 · 评论 0 条

VBA 日期处理:Date、Now、Format

在 VBA 编程中,日期和时间处理是最频繁的需求之一。无论是记录业务操作时间、生成报表、还是计算时间差,都离不开日期相关函数。本文将详细介绍 VBA 中最常用的三个日期处理函数:DateNowFormat,并通过实际案例展示它们的用法。


一、VBA 日期类型的基本概念

在 VBA 中,日期和时间是以浮点数的形式存储的。整数部分代表日期(从 1899 年 12 月 30 日开始计算),小数部分代表时间(0 表示午夜,0.5 表示中午,0.99999 表示距离午夜不到 1 秒)。理解这一底层机制有助于你更好地掌握日期运算。

日期值 44562.5 = 2022年1月15日中午12:00

二、Date 函数:获取当前日期

Date 函数返回当前系统日期,不包含时间部分。这是 VBA 中获取"今天"最简单直接的方式。

基本语法

Dim today As Date
today = Date

Date 函数不需要任何参数,调用它就会返回当前日期。

实用场景

场景一:记录数据录入日期

Sub RecordEntryDate()
    Dim ws As Worksheet
    Set ws = ThisWorkbook.Sheets("Sheet1")

    ' 在A列最后一行写入当前日期
    Dim lastRow As Long
    lastRow = ws.Cells(ws.Rows.Count, 1).End(xlUp).Row + 1

    ws.Cells(lastRow, 1).Value = Date
    ws.Cells(lastRow, 2).Value = "新录入"
End Sub

场景二:判断数据是否过期

Sub CheckExpiredItems()
    Dim ws As Worksheet
    Set ws = ThisWorkbook.Sheets("库存")

    Dim i As Long
    For i = 2 To ws.Cells(ws.Rows.Count, 1).End(xlUp).Row
        ' C列是有效期
        If ws.Cells(i, 3).Value < Date Then
            ws.Cells(i, 4).Value = "已过期"
            ws.Cells(i, 4).Interior.Color = RGB(255, 200, 200)
        Else
            ws.Cells(i, 4).Value = "有效"
        End If
    Next i
End Sub

进阶用法:日期计算

由于 VBA 日期本质是数字,你可以直接进行加减运算。

Sub DateCalculation()
    Dim today As Date
    today = Date

    ' 一周后的日期
    Dim nextWeek As Date
    nextWeek = today + 7

    ' 30天后的日期
    Dim thirtyDaysLater As Date
    thirtyDaysLater = today + 30

    ' 上月的最后一天
    Dim lastMonthEnd As Date
    lastMonthEnd = DateAdd("d", -Day(today), today)

    Debug.Print "今天是: " & today
    Debug.Print "一周后: " & nextWeek
    Debug.Print "30天后: " & thirtyDaysLater
    Debug.Print "上月最后一天: " & lastMonthEnd
End Sub

三、Now 函数:获取当前日期和时间

Now 函数返回当前系统的完整日期和时间,精确到秒。与 Date 不同,Now 同时包含日期和时间信息。

基本语法

Dim now As Date
now = Now

实用场景

场景一:记录操作时间戳

Sub RecordOperationTimestamp()
    Dim ws As Worksheet
    Set ws = ThisWorkbook.Sheets("日志")

    Dim lastRow As Long
    lastRow = ws.Cells(ws.Rows.Count, 1).End(xlUp).Row + 1

    ws.Cells(lastRow, 1).Value = Now
    ws.Cells(lastRow, 2).Value = Environ("Username")  ' 获取用户名
    ws.Cells(lastRow, 3).Value = "数据更新"
End Sub

场景二:计算程序执行时间

Sub MeasureExecutionTime()
    Dim startTime As Date
    Dim endTime As Date
    Dim duration As Double

    startTime = Now

    ' ===== 这里是需要计时的代码 =====
    Dim i As Long
    For i = 1 To 100000
        Cells(i Mod 100 + 1, 1).Value = i
    Next i
    ' ===== 计时代码结束 =====

    endTime = Now

    ' 计算耗时(秒)
    duration = DateDiff("s", startTime, endTime)

    MsgBox "程序执行耗时: " & duration & " 秒"
End Sub

Date 与 Now 的区别

函数 返回值 适用场景
Date 2024/3/15 只关心日期,如有效期、截止日
Now 2024/3/15 14:30:25 需要精确时间,如日志、计时

四、Format 函数:格式化日期与时间

Format 函数是 VBA 中最强大的格式化工具,它可以将日期转换为任意你需要的字符串格式。掌握 Format 是日期处理的关键技能。

基本语法

Format(expression, [format], [firstdayofweek], [firstweekofyear])
  • expression:要格式化的值(日期、数字或字符串)
  • format:格式模板,可选预定义格式或自定义格式

预定义格式

VBA 提供了一系列预定义格式,可以快速使用:

Sub PredefinedFormats()
    Dim dt As Date
    dt = Now

    Debug.Print "General Date: " & Format(dt, "General Date")
    Debug.Print "Long Date: " & Format(dt, "Long Date")
    Debug.Print "Medium Date: " & Format(dt, "Medium Date")
    Debug.Print "Short Date: " & Format(dt, "Short Date")
    Debug.Print "Long Time: " & Format(dt, "Long Time")
    Debug.Print "Medium Time: " & Format(dt, "Medium Time")
    Debug.Print "Short Time: " & Format(dt, "Short Time")
End Sub

输出示例:

General Date: 2024/3/15
Long Date: 2024年3月15日
Medium Date: 24/03/15
Short Date: 2024/3/15
Long Time: 14:30:25
Medium Time: 02:30 下午
Short Time: 14:30

自定义格式

自定义格式让你可以精确控制输出的每一个部分:

Sub CustomFormats()
    Dim dt As Date
    dt = #3/15/2024 2:30:25 PM#

    ' 年
    Debug.Print "yyyy: " & Format(dt, "yyyy")   ' 2024
    Debug.Print "yy: " & Format(dt, "yy")       ' 24

    ' 月
    Debug.Print "mmmm: " & Format(dt, "mmmm")   ' March
    Debug.Print "mmm: " & Format(dt, "mmm")     ' Mar
    Debug.Print "mm: " & Format(dt, "mm")       ' 03 (两位数字)
    Debug.Print "m: " & Format(dt, "m")         ' 3 (一位或两位)

    ' 日
    Debug.Print "dddd: " & Format(dt, "dddd")   ' Friday
    Debug.Print "ddd: " & Format(dt, "ddd")     ' Fri
    Debug.Print "dd: " & Format(dt, "dd")       ' 15

    ' 时间
    Debug.Print "hh: " & Format(dt, "hh")       ' 02 (12小时制)
    Debug.Print "HH: " & Format(dt, "HH")       ' 14 (24小时制)
    Debug.Print "nn: " & Format(dt, "nn")       ' 30 (分钟)
    Debug.Print "ss: " & Format(dt, "ss")       ' 25 (秒)
    Debug.Print "AM/PM: " & Format(dt, "AM/PM") ' PM
End Sub

常用格式组合示例

Sub CommonFormatExamples()
    Dim dt As Date
    dt = Now

    ' 中文格式
    Debug.Print "中文完整: " & Format(dt, "yyyy年mm月dd日")           ' 2024年03月15日
    Debug.Print "中文短: " & Format(dt, "yy/mm/dd")                   ' 24/03/15

    ' 英文格式
    Debug.Print "美式: " & Format(dt, "MM/DD/YYYY")                   ' 03/15/2024
    Debug.Print "英式: " & Format(dt, "DD/MM/YYYY")                   ' 15/03/2024
    Debug.Print "ISO: " & Format(dt, "YYYY-MM-DD")                    ' 2024-03-15

    ' 带时间格式
    Debug.Print "完整: " & Format(dt, "yyyy-mm-dd hh:nn:ss")          ' 2024-03-15 14:30:25
    Debug.Print "简洁: " & Format(dt, "mm/dd hh:nn")                  ' 03/15 14:30
    Debug.Print "12小时: " & Format(dt, "yyyy-mm-dd hh:nn:ss AM/PM")  ' 2024-03-15 02:30:25 PM

    ' 只显示部分
    Debug.Print "只显示月份: " & Format(dt, "mmmm yyyy")              ' March 2024
    Debug.Print "只显示时间: " & Format(dt, "hh:nn")                  ' 14:30
    Debug.Print "只显示周几: " & Format(dt, "aaaa")                   ' 星期五
End Sub

格式中的转义字符

如果格式字符本身需要作为普通文本显示,需要用双引号括起来:

Sub FormatWithText()
    Dim dt As Date
    dt = #3/15/2024#

    ' 在格式中加入普通文本
    Debug.Print "文本1: " & Format(dt, "yyyy年mm月dd日")     ' 2024年03月15日
    Debug.Print "文本2: " & Format(dt, "今天是 yyyy/mm/dd")  ' 今天是 2024/03/15

    ' 用引号包裹任意文本
    Debug.Print "文本3: " & Format(dt, "dd""日"" mm""月""") ' 15日 03月
End Sub

五、综合实战案例

案例一:自动生成带日期的报表文件名

Sub GenerateReportFilename()
    Dim reportDate As Date
    reportDate = Date

    Dim filename As String
    filename = "销售报表_" & Format(reportDate, "yyyymmdd") & ".xlsx"

    Debug.Print "文件名: " & filename
    ' 输出: 销售报表_20240315.xlsx

    ' 实际保存文件
    Dim savePath As String
    savePath = "C:\Reports\" & filename

    ' 如果目录不存在则创建
    Dim fso As Object
    Set fso = CreateObject("Scripting.FileSystemObject")
    If Not fso.FolderExists("C:\Reports") Then
        fso.CreateFolder ("C:\Reports")
    End If

    ' 保存工作簿
    ThisWorkbook.SaveAs savePath
End Sub

案例二:计算业务年龄和工龄

Sub CalculateServiceYear()
    Dim ws As Worksheet
    Set ws = ThisWorkbook.Sheets("员工信息")

    Dim lastRow As Long
    lastRow = ws.Cells(ws.Rows.Count, 1).End(xlUp).Row

    Dim i As Long
    For i = 2 To lastRow
        Dim birthDate As Date
        Dim hireDate As Date
        Dim today As Date

        birthDate = ws.Cells(i, 3).Value  ' C列:出生日期
        hireDate = ws.Cells(i, 4).Value   ' D列:入职日期
        today = Date

        ' 计算年龄(精确到月)
        Dim ageMonths As Long
        ageMonths = DateDiff("m", birthDate, today)
        If Day(today) < Day(birthDate) Then
            ageMonths = ageMonths - 1
        End If

        ' 计算工龄(精确到月)
        Dim serviceMonths As Long
        serviceMonths = DateDiff("m", hireDate, today)

        ' 写入结果
        ws.Cells(i, 5).Value = ageMonths \ 12 & "岁" & ageMonths Mod 12 & "个月"
        ws.Cells(i, 6).Value = serviceMonths \ 12 & "年" & serviceMonths Mod 12 & "个月"

        ' 格式化显示
        ws.Cells(i, 5).NumberFormat = "@"
        ws.Cells(i, 6).NumberFormat = "@"
    Next i

    MsgBox "计算完成!"
End Sub

案例三:生成工作日日历

Sub GenerateWorkdayCalendar()
    Dim startDate As Date
    Dim endDate As Date
    Dim currentDate As Date

    startDate = Date        ' 从今天开始
    endDate = DateAdd("m", 3, startDate)  ' 三个月后

    Dim ws As Worksheet
    Set ws = ThisWorkbook.Sheets("日历")
    ws.Cells.Clear

    ' 写入表头
    ws.Range("A1").Value = "日期"
    ws.Range("B1").Value = "星期"
    ws.Range("C1").Value = "是否工作日"

    Dim rowNum As Long
    rowNum = 2
    currentDate = startDate

    Do While currentDate <= endDate
        ws.Cells(rowNum, 1).Value = currentDate
        ws.Cells(rowNum, 1).NumberFormat = "yyyy-mm-dd"

        ws.Cells(rowNum, 2).Value = Format(currentDate, "aaaa")

        ' 判断是否周末(周六=7,周日=1)
        Dim weekDay As Integer
        weekDay = Weekday(currentDate, vbSunday)

        If weekDay = 1 Or weekDay = 7 Then
            ws.Cells(rowNum, 3).Value = "周末"
            ws.Cells(rowNum, 3).Interior.Color = RGB(220, 220, 220)
        Else
            ws.Cells(rowNum, 3).Value = "工作日"
        End If

        rowNum = rowNum + 1
        currentDate = currentDate + 1
    Loop

    ' 自动调整列宽
    ws.Columns("A:C").AutoFit

    MsgBox "日历生成完成,共 " & (rowNum - 2) & " 天"
End Sub

六、常见问题与解决方案

问题一:日期显示为数字

有时从Excel读取日期时,发现它显示为数字(如44562),这是因为Excel单元格格式被更改。

Sub FixDateDisplay()
    Dim cell As Range
    For Each cell In Selection
        If IsDate(cell.Value) Then
            ' 恢复为日期格式
            cell.NumberFormat = "yyyy-mm-dd"
        End If
    Next cell
End Sub

问题二:日期比较不准确

比较日期时,时间部分可能导致意外结果。

Sub DateCompareIssue()
    Dim date1 As Date
    Dim date2 As Date

    date1 = #3/15/2024 10:00:00 AM#
    date2 = #3/15/2024#

    ' 直接比较会失败,因为有时间部分
    Debug.Print date1 = date2  ' False

    ' 解决方法:使用 DateValue 去除时间部分
    Debug.Print DateValue(date1) = DateValue(date2)  ' True
    Debug.Print DateValue(date1) = date2  ' True
End Sub

问题三:时区问题

DateNow 获取的是系统本地时间。在跨时区应用中需要注意。

Sub HandleTimezone()
    ' 获取UTC时间
    Dim utcNow As Date
    utcNow = Now + TimeZoneOffset()  ' 需要自行计算时区差

    ' 本地时间转UTC
    Dim localToUtc As Date
    localToUtc = DateAdd("h", -8, Now)  ' 假设本地是UTC+8

    ' 格式化时明确时区
    Dim isoFormat As String
    isoFormat = Format(utcNow, "yyyy-mm-ddTHH:nn:ss") & "Z"  ' Z表示UTC
    Debug.Print isoFormat
End Sub

七、日期处理函数速查表

函数/关键字 作用 示例
Date 返回当前日期 Date → 2024/3/15
Now 返回当前日期和时间 Now → 2024/3/15 14:30
Time 返回当前时间 Time → 14:30:25
Format 格式化日期/时间 Format(d, "yyyy-mm-dd")
DateValue 提取日期部分 DateValue(Now) → 2024/3/15
TimeValue 提取时间部分 TimeValue(Now) → 14:30:25
DateDiff 计算日期间隔 DateDiff("d", d1, d2)
DateAdd 添加时间间隔 DateAdd("m", 1, d)
Weekday 返回星期几 Weekday(d, vbSunday)
Day 提取日 Day(d) → 15
Month 提取月 Month(d) → 3
Year 提取年 Year(d) → 2024

掌握这三个核心函数——DateNowFormat——能够满足 VBA 开发中 90% 以上的日期处理需求。建议在实际项目中多多练习,将这些函数的使用内化为本能。

评论 (0)

暂无评论,快来抢沙发吧!

扫一扫,手机查看

扫描上方二维码,在手机上查看本文