TIL 仓库笔记详解:使用 ~D 日期 Sigil 创建 Elixir Date 结构体
发布时间:2026/10/4 14:32:06 锦皓数字建站

文档教程知识库【免费下载链接】til:memo: Today I Learned项目地址https://gitcode.com/gh_mirrors/ti/til点击查看免费下载本文围绕仓库中的 elixir/create-a-date-with-the-date-sigil.md 展开系统讲解 Elixir 1.3 引入的~D日期 sigil它的语法、与Date.new/3的等价关系、Date结构体的字段访问方式以及在模块代码、IEx 交互环境中的实际用法。读完本文你将能熟练地用~D在代码中直接书写日期字面量并理解它与~T、~N、~U等姊妹 sigil 的关系为日常的日期处理代码打下基础。背景Elixir 1.3 的日期与时间革命在 Elixir 1.3 之前处理日期和时间通常需要借助 Erlang 原语或引入 Timex 记录了那个时代的典型做法——直接调用:erlang.time拿到{时, 分, 秒}元组再手动拼接字符串。Elixir 1.3 改变了这一切标准库正式引入了基于Calendar模块的整套日期与时间类型包括Date、Time、NaiveDateTime、DateTime并为它们配套提供了专用的sigil字符选择器。elixir/create-a-date-with-the-date-sigil.md 记录的正是其中用于创建日期的~Dsigil。~D的工作方式与Date模块的new/3函数完全一致解析传入的日期字符串生成一个包含各日期组成部分年、月、日的Date结构体。不同之处只在于语法——sigil 提供了一种更简洁、更接近字面量的书写方式。~D 的基本语法与 IEx 中的第一手体验~D的完整语法由三部分组成~Dsigil 名称定界符[...]包裹日期内容也支持~D{...}、~D{...}等其他定界符日期字符串YYYY-MM-DD严格按照 ISO 8601 的年-月-日格式书写。仓库文档给出的最基础示例可以直接在 IEx 中运行 ~D[2016-01-01] ~D[2016-01-01] ~D[2016-01-01].year 2016 ~D[2016-01-01].month 1 ~D[2016-01-01].day 1第一行输出了一个合法的Date结构体其 IEx 渲染形式恰好就是~D[2016-01-01]方便复制回代码里继续使用。后三行则展示了字段访问.year返回2016、.month返回1、.day返回1——这三个字段共同构成了一个日期。值得注意的是~D要求传入的必须是合法日期。与 JavaScript 中new Date(...)的宽松行为不同非法输入例如~D[2016-02-30]这种不存在的 2 月 30 日会直接抛出ArgumentError从而把日期校验提前到写下代码的那一刻避免脏数据悄悄流入业务逻辑。与 Date.new/3 的等价关系原文档明确指出~D的作用与Date.new/3函数相同。所谓Date.new/3即Date.new(year, month, day)它接收三个整数并返回带标签的元组 Date.new(2016, 1, 1) {:ok, ~D[2016-01-01]} Date.new(2016, 13, 1) {:error, :invalid_date}两者的对比如下创建方式示例返回类型适用场景~Dsigil~D[2016-01-01]直接返回Date结构体写死日期字面量如生日、固定节假日、测试夹具Date.new/3Date.new(2016, 1, 1)返回{:ok, date}或{:error, reason}运行时动态构造日期需要处理非法输入一个关键差异在于返回值形态~D在写下的瞬间就完成了校验并直接给出结构体而Date.new/3返回的是 tagged tuple要求调用方显式匹配{:ok, date}分支。这决定了它们的使用场景硬编码日期优先用~D由用户输入或外部数据动态组装日期时则用Date.new/3配合模式匹配处理错误分支。访问 Date 结构体的字段Date是一个普通的 Elixir 结构体struct定义于 Elixir 标准库的Date模块。除文档中演示的year、month、day之外它还有一个calendar字段默认指向Calendar.ISO。结构体的字面形式如下%Date{ calendar: Calendar.ISO, day: 1, month: 1, year: 2016 }正因为它是普通结构体你可以用点语法读取任意字段也可以把它当作模式匹配的载体iex ~D[2016-01-01] %Date{calendar: Calendar.ISO, day: 1, month: 1, year: 2016} ~D[2016-01-01] # 也可以只匹配关心的字段 iex %Date{year: y, month: m} ~D[2016-01-01] ~D[2016-01-01] iex y 2016 iex m 1如果后续需要把日期输出成字符串例如写入日志或返回给前端可以用Date.to_string/1 Date.to_string(~D[2016-01-01]) 2016-01-01而结构体级别的相等性比较直接用即可当需要判断两个日期谁先谁后时则用Date.compare/2它会返回:lt、:gt或:eq。把 ~D 写进模块代码函数封装与编译期常量~D在模块内书写时属于 sigil 语法糖会在编译期被展开求值因此它实际上是一个编译期常量。这意味着你可以放心地把这类日期写进模块属性和函数默认值里不会有任何运行时解析开销defmodule User do default_birthday ~D[1990-06-15] def default_birthday, do: default_birthday end也可以封装成具名函数让语义更清晰defmodule Holiday do def new_year, do: ~D[2016-01-01] def independence_day, do: ~D[2016-07-04] end在测试代码中~D尤其好用——它让测试夹具fixture里的日期一目了然且不依赖系统时间天然具备确定性。例如配合 Ecto 的 schema 做数据断言时可以直接写出assert user.birthday ~D[1990-06-15]这样的可读性极佳的比较。与 ~T、~N、~U 姊妹 sigil 的关系~D并不是孤立的Elixir 1.3 起标准库还提供了一套配套的时间类 sigil覆盖日期之外的时刻Sigil生成结构体示例说明~D[...]Date~D[2016-01-01]仅日期无时间与时区~T[...]Time~T[13:26:08]仅时间无日期与时区~N[...]NaiveDateTime~N[2016-05-24 13:26:08.003]日期 时间无时区信息~U[...]DateTime~U[2016-05-24 13:26:08Z]日期 时间 UTC 时区其中~N和~U经常需要转换成DateTime后使用仓库中的两个 Elixir 笔记正好演示了这一组合elixir/comparing-datetime-structs.md 中通过DateTime.from_naive(~N[2016-05-24 13:26:08.003], Etc/UTC)把 naive datetime 挂上时区再调用DateTime.compare/2比较先后elixir/check-list-membership.md 同样先构造~N[2016-05-24 13:26:08.003]再配合DateTime.compare/2与in操作符判断某个时间是否落在过去或现在区间内。可以看到~N、~U这类带完整时刻的 sigil 通常只是数据入口真正的逻辑处理还是要交给NaiveDateTime/DateTime模块的函数而~D因为只关心年月日往往可以直接参与比较和运算是最独立的一个。小结~D是 Elixir 1.3 提供的最直观的日期构造方式。回顾仓库笔记的核心要点~D[2016-01-01]按 ISO 8601 格式直接生成Date结构体等价于Date.new(2016, 1, 1)生成后的结构体可通过.year、.month、.day等字段直接访问各部分非法日期会在构造时抛出ArgumentError将校验提前到写代码阶段在模块中使用时它是编译期常量适合做日期字面量、测试夹具和函数默认值与~T、~N、~U共同构成 Elixir 标准库的日期时间 sigil 家族各司其职。如果你的项目仍停留在调:erlang.time或引入重量级库的阶段不妨像 elixir/do-you-have-the-time-part-2.md 建议的那样先用标准库的 sigil 和模块函数把逻辑写简洁——~D正是这个思路下最基础、最常用的一块积木。赞分享文档教程知识库【免费下载链接】til:memo: Today I Learned项目地址https://gitcode.com/gh_mirrors/ti/til点击查看免费下载相关推荐Delve 后端测试健康报告全解读各平台跳过测试统计、原因分类与生成机制Delve 后端测试健康报告全解读各平台跳过测试统计、原因分类与生成机制 Documentation/backend_test_health.md 是 Del文档教程知识库JavaScript 日期创建实战用 new Date 构造指定日期Modern JavaScript Tutorial 习题精解JavaScript 日期创建实战用 new Date 构造指定日期Modern JavaScript Tutorial 习题精解 导读 在 JavaSc文档/教程前端TIL 仓库笔记ack 命令行工具的隐藏彩蛋 --bar 选项TIL 仓库笔记ack 命令行工具的隐藏彩蛋 bar 选项 本篇技术笔记围绕本仓库 ack 分类 https://link.gitcode.com/i/2a6文档教程知识库上一篇F´ (F Prime) SystemResources 组件深度解析系统内存、CPU 与磁盘遥测下传机制下一篇GitHub Actions 自定义 Runner 镜像构建指南从 Toolset 到生产部署的 3 层 Packer 配置全解创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
锦
锦皓数字建站
深耕本土企业品牌数字化升级,专注原创端正雅致商务官网,从视觉设计到稳定运维全程保驾护航。