Julia 日期与时间完全指南(中文 + 实战)
“精确、时区感知、纳秒级” —— Julia 的
Dates模块是科学计算与金融系统的首选
一、核心类型总览
| 类型 | 用途 | 示例 |
|---|---|---|
Date | 年-月-日 | 2025-10-26 |
DateTime | 年-月-日 时:分:秒.毫秒 | 2025-10-26T14:30:22.123 |
Time | 时:分:秒.纳秒 | 14:30:22.123456789 |
Period | 时间段(如 Day(1)) | Month(3) |
Instant | 绝对时间点(内部用) | — |
二、导入与基本创建
using Dates
# 1. 字面量(推荐)
d = Date(2025, 10, 26) # Date
dt = DateTime(2025, 10, 26, 14, 30, 22) # DateTime
t = Time(14, 30, 22, 123, 456, 789) # Time
# 2. 字符串解析
Date("2025-10-26") # ISO 8601
Date("26/10/2025", "dd/mm/yyyy")
DateTime("2025-10-26T14:30:22")
支持格式:
dateformat"yyyy-mm-dd"等
三、当前时间
now() # DateTime: 2025-10-26T14:30:22.123
today() # Date: 2025-10-26
now(UTC) # UTC 时间
四、时间运算(核心!)
d1 = Date(2025, 10, 26)
d2 = Date(2025, 11, 26)
# 加减 Period
d1 + Day(1) # 2025-10-27
d2 - Month(1) # 2025-10-26
d2 - d1 # Day(31)
# 时间段
dt1 = DateTime(2025, 10, 26, 0, 0)
dt2 = DateTime(2025, 10, 26, 1, 30, 30)
dt2 - dt1 # Millisecond(5430000) = 1h30m30s
# 比较
d1 < d2 # true
dt1 == dt2 # false
Period 类型
| 类型 | 示例 | 说明 |
|---|---|---|
Year, Month | Year(1) | 按日历 |
Day, Hour, Minute, Second | Day(1) | 按固定长度 |
Millisecond, Microsecond, Nanosecond | Millisecond(500) | 高精度 |
Date(2024, 2, 29) + Year(1) # 2025-02-28(闰年处理!)
Date(2024, 2, 29) + Day(366) # 2025-02-28
五、时间格式化与解析
# 定义格式
fmt = dateformat"yyyy-mm-dd HH:MM:SS"
# 格式化
string(dt, fmt) # "2025-10-26 14:30:22"
Dates.format(dt, "dd/u/yyyy") # "26/Oct/2025"
# 解析
DateTime("26/10/2025", "dd/mm/yyyy")
常用格式符
| 符 | 含义 | 示例 |
|---|---|---|
y | 年(短) | 25 |
yyyy | 年(长) | 2025 |
m | 月(数字) | 1–12 |
mm | 月(补0) | 01–12 |
u | 月(英文) | Jan |
d | 日 | 1–31 |
dd | 日(补0) | 01–31 |
HH | 小时(24制) | 00–23 |
MM | 分钟 | 00–59 |
SS | 秒 | 00–59 |
s | 毫秒 | 000–999 |
六、时间组件提取
dt = DateTime(2025, 10, 26, 14, 30, 22, 123)
year(dt) # 2025
month(dt) # 10
day(dt) # 26
hour(dt) # 14
minute(dt) # 30
second(dt) # 22
millisecond(dt) # 123
dayofweek(dt) # 7(周日)
dayname(dt) # "Sunday"
monthname(dt) # "October"
七、时间范围与遍历
# 日期范围
dr = Date(2025, 10, 1):Day(1):Date(2025, 10, 31)
for d in dr
println(d)
end
# 每小时
dtr = DateTime(2025, 10, 26, 0, 0):Hour(1):DateTime(2025, 10, 26, 23, 0)
八、时区支持(TimeZones.jl)
需安装:
] add TimeZones
using TimeZones
# 本地时间 → 带时区
local_dt = now()
zdt = ZonedDateTime(local_dt, localzone()) # 如 Asia/Shanghai
# 固定时区
utc_dt = ZonedDateTime(2025, 10, 26, 14, 30, tz"UTC")
ny_dt = ZonedDateTime(2025, 10, 26, 10, 30, tz"America/New_York")
# 转换
astimezone(utc_dt, tz"Asia/Shanghai")
九、时间计算函数
# 季度
quarterofyear(dt) # 4
# 周数
week(dt) # 43
# 一年中的第几天
dayofyear(dt) # 299
# 月末
lastdayofmonth(dt) # 2025-10-31
# 调整到月初/季初
firstdayofmonth(dt) # 2025-10-01
firstdayofquarter(dt) # 2025-10-01
十、时间差分解(canonicalize)
dt1 = DateTime(2025, 1, 1)
dt2 = DateTime(2025, 12, 31, 23, 59, 59)
diff = dt2 - dt1
canonicalize(diff)
# CompoundPeriod: 11 months, 30 days, 23 hours, 59 minutes, 59 seconds
十一、综合示例:工作日判断
is_business_day(d::Date) =
dayofweek(d) ∉ (Saturday, Sunday) &&
!(Month(d) == 1 && Day(d) == 1) # 简化:排除元旦
# 下一个工作日
function next_business_day(d::Date)
d += Day(1)
while !is_business_day(d)
d += Day(1)
end
return d
end
十二、综合示例:时间序列生成
function trading_days(start_year::Int, end_year::Int)
days = Date[]
for y in start_year:end_year
for m in 1:12
for d in 1:31
date = Date(y, m, d)
try
is_business_day(date) && push!(days, date)
catch
continue # 无效日期
end
end
end
end
return days
end
十三、性能建议
| 建议 | 说明 |
|---|---|
用 Date 而非 DateTime | 节省内存 |
| 批量操作用范围 | dr = start:Day(1):end |
避免频繁 now() | 缓存或用定时器 |
高精度用 Nanosecond | Time 支持纳秒 |
# 快:预分配
dates = Vector{Date}(undef, 1000)
for (i, d) in enumerate(Date(2025,1,1):Day(1):Date(2025,1,1000))
dates[i] = d
end
十四、速查表
| 操作 | 语法 |
|---|---|
| 创建 | Date(y,m,d), DateTime(...) |
| 当前 | now(), today() |
| 解析 | Date("2025-10-26") |
| 格式化 | Dates.format(dt, "yyyy-mm-dd") |
| 加减 | dt + Hour(1), d - Day(1) |
| 比较 | dt1 < dt2 |
| 提取 | year(dt), hour(dt) |
| 范围 | Date(2025,1,1):Day(1):Date(2025,12,31) |
| 时区 | ZonedDateTime(dt, tz"Asia/Shanghai") |
十五、小练习(立即上手)
- 计算两个日期相差多少个工作日
- 将
"2025-10-26 14:30:22"转为 UTC 时间 - 生成 2025 年每月最后一个交易日
- 解析
"3 days ago"字符串 - 实现
age(birth::Date)返回当前年龄
答案示例
# 1. 工作日差
function business_days_between(d1::Date, d2::Date)
count = 0
d = d1 + Day(1)
while d < d2
is_business_day(d) && (count += 1)
d += Day(1)
end
return count
end
# 2. 转 UTC
using TimeZones
local_str = "2025-10-26 14:30:22"
local_dt = DateTime(local_str, dateformat"yyyy-mm-dd HH:MM:SS")
zdt = ZonedDateTime(local_dt, localzone())
astimezone(zdt, tz"UTC")
# 3. 月末交易日
[next_business_day(lastdayofmonth(Date(2025, m, 1)) – Day(1)) for m in 1:12]
# 4. 解析 “3 days ago” function parse_relative(s) m = match(r”(\d+)\s+(second|minute|hour|day|week|month|year)s?\s+ago”, s) n, unit = parse(Int, m[1]), m[2] period = eval(Symbol(unit[1:end-1] * “s”))(n) return now() – period end # 5. 年龄 age(birth::Date) = floor(Int, (today() – birth) / Year(1))
十六、常见错误与避坑
| 错误 | 正确做法 |
|---|---|
Date("2025/10/26") | 用 dateformat"yyyy/mm/dd" |
dt + 1 | 必须加 Day(1) |
DateTime 存日期 | 用 Date 节省内存 |
| 忽略时区 | 金融/日志必用 ZonedDateTime |
恭喜!你已精通 Julia 日期与时间!
现在你可以:
- 处理金融时间序列
- 构建调度系统
- 解析任意格式日志
- 实现时区转换
下一站推荐
| 主题 | 为什么学 |
|---|---|
DataFrames + Dates | 时间序列分析 |
TimeSeries.jl | 专业金融 |
CSV.jl 读取时间列 | 实战导入 |
Plots.jl 时间轴 | 可视化 |
TimerOutputs.jl | 性能计时 |
需要我:
- 写一个 股票数据分析器?
- 实现 倒计时调度器?
- 构建 日志时间解析器(支持多种格式)?
- 绘制 2025年交易日热图?
随时告诉我!