强曰为道
与天地相似,故不违。知周乎万物,而道济天下,故不过。旁行而不流,乐天知命,故不忧.
文档目录

Julia 教程 / Julia 日期、时间与周期

17. 日期、时间与周期

Dates 模块是 Julia 标准库中处理日期和时间的完整工具包,提供类型安全的日期运算和丰富的格式化能力。

17.1 Date/DateTime/Time 类型

三种核心类型

using Dates

# Date — 仅日期(无时间)
d = Date(2026, 5, 11)
println(d)  # 2026-05-11

# DateTime — 日期+时间
dt = DateTime(2026, 5, 11, 14, 30, 0)
println(dt)  # 2026-05-11T14:30:00

# Time — 仅时间(无日期)
t = Time(14, 30, 0)
println(t)  # 14:30:00

# 当前时间
println(now())       # DateTime
println(today())     # Date
println(now(Time))   # Time

类型层次

# AbstractDateTime
# ├── TimeType
# │   ├── Date        — 日期
# │   └── DateTime    — 日期时间
# └── Time            — 时间(独立)
类型精度示例
DateDate(2026, 5, 11)
DateTime毫秒DateTime(2026, 5, 11, 14, 30)
Time纳秒Time(14, 30, 0)

构造方式

# 从字符串构造
d1 = Date("2026-05-11")
dt1 = DateTime("2026-05-11T14:30:00")
t1 = Time("14:30:00")

# 使用关键字参数
d2 = Date(2026, 5)
dt2 = DateTime(2026, 5, 11, 14)

# 从 Unix 时间戳
epoch = DateTime(1970, 1, 1)
dt_from_ts = epoch + Second(1715428200)

17.2 日期解析与格式化

格式化符号

符号含义示例
yyyy四位年2026
mm两位月05
dd两位日11
HH24小时14
MM分钟30
SS00
EEEE星期全名Sunday
E星期缩写Sun

解析日期

# 自定义格式解析
d = Date("11/05/2026", dateformat"dd/mm/yyyy")
println(d)  # 2026-05-11

dt = DateTime("2026年05月11日 14:30", dateformat"yyyy年mm月dd日 HH:MM")
println(dt)

# 中文日期解析
d2 = Date("2026年5月11日", dateformat"yyyy年m月d日")

格式化输出

d = Date(2026, 5, 11)

# 使用 format 函数
println(Dates.format(d, dateformat"yyyy-mm-dd"))    # 2026-05-11
println(Dates.format(d, dateformat"dd/mm/yyyy"))    # 11/05/2026
println(Dates.format(d, dateformat"yyyy年mm月dd日")) # 2026年05月11日

dt = DateTime(2026, 5, 11, 14, 30, 45)
println(Dates.format(dt, dateformat"yyyy-mm-dd HH:MM:SS"))
# 2026-05-11 14:30:45

# dayname / dayofweek
println(Dates.dayname(d))   # Sunday (或中文系统下的星期日)
println(Dates.dayofweek(d)) # 7

17.3 日期运算

周期类型

using Dates

d = Date(2026, 1, 15)

# Period 类型
d + Day(1)      # +1天
d + Week(2)     # +2周
d + Month(3)    # +3月
d + Year(1)     # +1年

# 减法
d - Day(10)

# 组合运算
d + Month(1) + Day(15)  # 2026-03-02

日期差值

d1 = Date(2026, 1, 1)
d2 = Date(2026, 12, 31)

# 日期差
diff = d2 - d1
println(typeof(diff))  # Day
println(value(diff))   # 364

# 转换为不同单位
diff_days = Dates.value(Day(d2 - d1))
diff_weeks = diff_days ÷ 7

# DateTime 差值
dt1 = DateTime(2026, 1, 1, 0, 0, 0)
dt2 = DateTime(2026, 1, 1, 12, 30, 0)
diff = dt2 - dt1
println(typeof(diff))  # Millisecond

比较运算

d1 = Date(2026, 1, 1)
d2 = Date(2026, 6, 15)

println(d1 < d2)    # true
println(d1 == d2)   # false
println(d1 > d2)    # false

# min / max
println(min(d1, d2))  # 2026-01-01
println(max(d1, d2))  # 2026-06-15

⚠️ 注意Month(1)Day(30) 不总相等(不同月份天数不同)。Julia 会自动处理月末溢出。

17.4 时区处理 (TimeZones.jl)

using TimeZones

# 创建带时区的时间
utc = ZonedDateTime(DateTime(2026, 5, 11, 14, 0), tz"UTC")
shanghai = astimezone(utc, tz"Asia/Shanghai")
println(shanghai)  # 2026-05-11T22:00:00+08:00

# 时区转换
nyc = astimezone(utc, tz"America/New_York")
tokyo = astimezone(utc, tz"Asia/Tokyo")

println("UTC:      $utc")
println("上海:     $shanghai")
println("纽约:     $nyc")
println("东京:     $tokyo")

# 获取当前时区时间
now_shanghai = now(tz"Asia/Shanghai")
println("上海现在: $now_shanghai")

时区列表

# 常用时区标识
# tz"UTC"           协调世界时
# tz"Asia/Shanghai"  中国标准时间 (UTC+8)
# tz"Asia/Tokyo"     日本标准时间 (UTC+9)
# tz"America/New_York" 美国东部时间
# tz"Europe/London"    英国时间

# 列出所有时区
# TimeZone[]  # 所有可用时区

17.5 日期范围与序列

创建日期范围

# 等间隔日期序列
dates = Date(2026, 1, 1):Day(1):Date(2026, 1, 10)
for d in dates
    println(d)
end
# 2026-01-01
# 2026-01-02
# ...
# 2026-01-10

# 月度序列
months = Date(2026, 1, 1):Month(1):Date(2026, 12, 1)
println(collect(months))  # 12个月的第一天

# 年度序列
years = Date(2020, 1, 1):Year(1):Date(2026, 1, 1)

生成日期列表

# 所有工作日
function workdays(start::Date, stop::Date)
    return filter(d -> Dates.dayofweek(d) <= 5, start:Day(1):stop)
end

wdays = workdays(Date(2026, 5, 1), Date(2026, 5, 31))
println("5月工作日: $(length(wdays)) 天")

# 月末日期
function month_ends(year)
    return [Dates.lastdayofmonth(Date(year, m, 1)) for m in 1:12]
end

println(month_ends(2026))

日期提取组件

d = DateTime(2026, 5, 11, 14, 30, 45)

println(year(d))        # 2026
println(month(d))       # 5
println(day(d))         # 11
println(hour(d))        # 14
println(minute(d))      # 30
println(second(d))      # 45
println(dayofweek(d))   # 1 (Monday=1)
println(dayofyear(d))   # 131
println(week(d))        # 19
println(daysinmonth(d)) # 31
println(isleapyear(d))  # false

17.6 性能计时

@elapsed

# @elapsed 返回执行时间(秒)
t = @elapsed sum(1:1_000_000)
println("耗时: $(round(t*1000, digits=2)) ms")

@timev

# @timev 提供详细计时信息
@timev begin
    data = rand(1000, 1000)
    result = data * data'
    s = sum(result)
end
# 输出:
#   0.123456 seconds (15 allocations: 15.259 MiB)
#   elapsed time (ns): 123456789
#   gc time (ns):      1234567
#   bytes allocated:   16000000
#   pool allocs:       15

@time

# @time 基本计时
@time result = sum(sin(x) for x in 1:10_000_000)
# 0.345678 seconds (4 allocations: 160 bytes)

BenchmarkTools.jl(推荐)

using BenchmarkTools

# @btime 自动多次运行取最优
@btime sum(1:1_000_000)
# 1.234 ms (0 allocations)

# @benchmark 详细统计
@benchmark sin(1.0)
# 输出最小、中位数、平均、最大时间

# 精确比较两种实现
@btime [sin(x) for x in 1:1000]     # 分配内存
@btime collect(sin(x) for x in 1:1000)  # 生成器

17.7 Dates 模块常用函数速查

创建函数

函数用途示例
Date(y,m,d)创建日期Date(2026,5,11)
DateTime(y,m,d,H,M,S)创建日期时间DateTime(2026,5,11,14,30)
Time(H,M,S)创建时间Time(14,30,0)
now()当前日期时间now()
today()当前日期today()

提取函数

函数用途示例
year(d)年份year(Date(2026,5,11)) → 2026
month(d)月份month(d) → 5
day(d)day(d) → 11
hour(dt)小时hour(now())
minute(dt)分钟minute(now())
second(dt)second(now())
dayofweek(d)星期几(1=Mon)dayofweek(d)
dayofyear(d)年内第几天dayofyear(d)
week(d)周数week(d)

查询函数

函数用途示例
isleapyear(d)是否闰年isleapyear(Date(2024,1,1))
daysinmonth(d)当月天数daysinmonth(d)
daysinyear(d)当年天数daysinyear(d)
isfinite(d)是否有限isfinite(d)

调整函数

函数用途示例
firstdayofmonth(d)月初firstdayofmonth(d)
lastdayofmonth(d)月末lastdayofmonth(d)
firstdayofyear(d)年初firstdayofyear(d)
lastdayofyear(d)年末lastdayofyear(d)
firstdayofweek(d)周一firstdayofweek(d)
lastdayofweek(d)周日lastdayofweek(d)

周期类型

类型含义示例
Year(n)n年d + Year(1)
Month(n)n月d + Month(6)
Week(n)n周d + Week(2)
Day(n)n天d + Day(7)
Hour(n)n小时dt + Hour(3)
Minute(n)n分钟dt + Minute(30)
Second(n)n秒dt + Second(45)
Millisecond(n)n毫秒dt + Millisecond(100)

17.8 实际应用:时间序列分析

生成时间序列

using Dates

# 每日数据
dates = Date(2026, 1, 1):Day(1):Date(2026, 12, 31)
values = cumsum(randn(length(dates)))  # 随机游走

# 每周聚合
function weekly_average(dates, values)
    weeks = Dict{Date, Vector{Float64}}()
    for (d, v) in zip(dates, values)
        week_start = d - Day(Dates.dayofweek(d) - 1)
        push!(get!(weeks, week_start, Float64[]), v)
    end
    sorted_weeks = sort(collect(weeks))
    return ([w for (w, _) in sorted_weeks],
            [mean(vs) for (_, vs) in sorted_weeks])
end

using Statistics
weekly_dates, weekly_vals = weekly_average(dates, values)
println("周平均值数量: $(length(weekly_dates))")

交易日历

# 工作日判断
is_workday(d::Date) = Dates.dayofweek(d) <= 5

# 计算交易日
function trading_days(start::Date, stop::Date)
    return filter(is_workday, start:Day(1):stop)
end

# N个交易日后
function add_trading_days(d::Date, n::Int)
    current = d
    added = 0
    while added < n
        current += Day(1)
        if is_workday(current)
            added += 1
        end
    end
    return current
end

start = Date(2026, 1, 1)
result = add_trading_days(start, 20)
println("20个交易日后: $result")

日期区间统计

function monthly_stats(dates, values)
    monthly = Dict{Tuple{Int,Int}, Vector{Float64}}()
    for (d, v) in zip(dates, values)
        key = (year(d), month(d))
        push!(get!(monthly, key, Float64[]), v)
    end
    
    for (ym, vals) in sort(collect(monthly))
        println("$(ym[1])-$(lpad(ym[2], 2, '0')): " *
                "均值=$(round(mean(vals), digits=2)), " *
                "标准差=$(round(std(vals), digits=2))")
    end
end

17.9 扩展阅读

资源链接
Julia 官方文档 - Dateshttps://docs.julialang.org/en/v1/stdlib/Dates/
TimeZones.jlhttps://github.com/JuliaTime/TimeZones.jl
BusinessDays.jlhttps://github.com/JuliaFinance/BusinessDays.jl
Dates 速查表https://docs.julialang.org/en/v1/stdlib/Dates/#Dates.format

17.10 本章小结

主题要点
三种类型Date(日)、DateTime(毫秒)、Time(纳秒)
解析格式化dateformat"yyyy-mm-dd" 自定义格式
日期运算Day/Month/Year 类型安全
时区TimeZones.jl 的 ZonedDateTime
日期范围start:step:stop 生成序列
组件提取year/month/day/hour
性能计时@time/@elapsed/BenchmarkTools