Linux date命令实战:格式化、时间戳与日期运算
1. 为什么“日期练习”值得单独拿出来做很多人第一次接触 Linux 命令行注意力都被ls、cd、grep这些“看得见摸得着”的命令吸引走了反而把date当成一个查时间的工具用完就忘。我刚开始也是这样直到有一次帮同事排查一个日志时间戳错乱的问题才发现自己对date的理解浅得可怜——时区、格式化、时间戳换算、日期加减几乎每一项都踩过坑。date这个命令表面上简单实际上它是 Linux 里少数几个“既能查、又能算、还能改”的多面手。查当前时间只是它最基础的功能真正有意思的是它的格式化输出、时间戳转换、日期偏移计算以及在脚本里做时间戳标记、日志切分、定时任务判断这些实战场景。换句话说date是 shell 脚本里出场率极高、但大多数人只用了它 20% 功能的命令。这篇内容适合谁看如果你是刚学 Linux 的新手想找一个切入点把命令行“用起来”那日期练习是个很好的抓手因为它反馈即时、场景具体、不容易劝退。如果你已经能熟练敲命令但每次遇到“算三天前是几号”“把时间戳转成可读格式”还要去搜那这篇正好帮你把这些零散知识串成一条线。我会从最基础的输出讲起一路讲到格式化、时间戳、日期运算和脚本里的实战用法中间穿插我自己踩过的坑和排查思路。需要先说明一点不同发行版、不同版本的date在参数上会有细微差别尤其是 GNU 版本和 BSD 版本差异明显。我下面讲的内容以常见的 GNU 版本为主也就是大多数主流发行版默认带的那套。如果你用的是别的版本遇到参数不认的情况先date --version看一眼再对照调整这个习惯能帮你省下大量试错时间。2. 基础输出与格式化把时间“捏”成你要的样子2.1 默认输出里藏着哪些信息直接敲date你会看到类似这样一行date # 输出示例Thu Mar 14 09:27:31 CST 2024这一行信息量其实不小。从左到右依次是星期缩写、月份缩写、日、时:分:秒、时区缩写、年份。很多人扫一眼就过去了但如果你要做日志分析就得知道每个字段的位置和含义。比如CST这个时区缩写就有歧义它既可能表示中国标准时间也可能表示美国中部时间具体取决于系统配置。所以真正严谨的场景里不要依赖这个缩写而是用后面要讲的格式化参数把时区明确输出出来。默认输出还有个特点它是给人看的不是给程序看的。字段宽度不固定月份和星期是英文缩写排序和解析都不方便。这就是为什么几乎所有正经脚本里都不会直接用裸date而是用格式化输出。2.2 用加号开头的格式串定制输出date最核心的用法就是加一个以开头的格式字符串里面用百分号占位符表示各个时间字段。比如date %Y-%m-%d %H:%M:%S # 输出示例2024-03-14 09:27:31这个格式串是脚本里出现频率最高的组合之一原因很直接YYYY-MM-DD HH:MM:SS这种写法既人类可读又能按字符串直接排序字典序和时间序一致。日志文件名、备份文件名、数据库导出文件名用这个格式几乎不会出错。常用的占位符我整理成一张表方便你对照查占位符含义示例输出%Y四位年份2024%m两位月份03%d两位日期14%H24小时制小时09%M分钟27%S秒31%sUnix 时间戳1710383251%A完整星期名Thursday%a星期缩写Thu%B完整月份名March%b月份缩写Mar%Z时区名称CST%z时区偏移0800%j一年中的第几天074%u星期几1-7周一为14这张表不用背用的时候查就行。但有几个组合我建议你直接记牢因为实战里反复出现%Y%m%d紧凑日期适合做文件名后缀比如backup_20240314.tar.gz%Y-%m-%d标准日期适合做数据库字段或报表%H:%M:%S纯时间适合做计时输出%s时间戳适合做计算和比较2.3 格式化里的几个易错点第一个坑是大小写。%m是月份%M是分钟%d是日期%D又是另一种日期格式。我见过不止一个新手把%M和%m写反结果输出里分钟变成了月份排查半天才发现是大小写问题。记住一个规律大写通常表示“更大的单位”或者“另一种表示”但这不是绝对规则最稳妥的办法还是查表。第二个坑是格式串必须用引号包起来。因为格式串里经常有空格不加引号的话 shell 会把空格当成参数分隔符date只会拿到前半截。比如date %Y-%m-%d %H:%M:%S不加引号%H:%M:%S会被当成另一个参数输出就不对了。养成习惯只要格式串里有空格或特殊字符一律加双引号。第三个坑是%本身。如果你想在输出里显示一个百分号得写%%。这个和很多编程语言的转义规则一致但容易忘。提示格式串里的字母大小写敏感写错一个字母输出就完全不同。建议把常用格式存成 shell 变量比如NOW$(date %Y-%m-%d %H:%M:%S)用的时候直接引用既避免重复写错也方便统一修改。3. 时间戳与日期运算让时间“可计算”3.1 Unix 时间戳到底是什么Unix 时间戳是从 1970 年 1 月 1 日 00:00:00 UTC 开始经过的秒数不包含闰秒。这个定义听起来抽象但你可以把它理解成“时间的统一货币”——不管哪个时区、哪种格式换算成时间戳之后都是同一个整数比较和计算就变得非常简单。用date %s就能拿到当前时间戳date %s # 输出示例1710383251反过来把时间戳转成可读格式用-d参数date -d 1710383251 # 输出示例Thu Mar 14 09:27:31 CST 2024注意符号不能省它告诉date后面跟的是时间戳而不是普通日期字符串。这个我刚开始老是忘忘了之后date会把那串数字当成年份去解析输出一个莫名其妙的日期排查起来还挺费劲。3.2 用 -d 做日期加减-d参数是date最强大的功能之一它接受自然语言描述的日期表达式。比如date -d 3 days ago %Y-%m-%d date -d next Monday %Y-%m-%d date -d 2024-03-14 10 days %Y-%m-%d date -d 1 month ago %Y-%m-%d这些表达式读起来几乎就是英文口语非常直观。实战里最常用的是“几天前”“几天后”这种相对计算比如算七天前的日期用来做日志清理date -d 7 days ago %Y%m%d这里有个细节值得说-d接受的表达式里ago表示往前或者直接写数字表示往后。但“一个月前”这种计算要小心因为月份长度不固定。比如 3 月 31 日往前一个月结果可能是 2 月 28 日或 29 日具体取决于实现。如果你的业务对日期边界敏感建议用天数计算而不是月份计算避免这种不确定性。3.3 时间戳做差算时间间隔两个时间戳相减就是秒数差这个特性在脚本里做计时非常方便START$(date %s) # 执行一些操作 sleep 3 END$(date %s) echo 耗时 $((END - START)) 秒这种写法比time命令更灵活因为你可以把计时逻辑嵌到脚本任意位置还能把结果写进日志。我做过一个批量处理脚本就是靠这种方式记录每个文件的处理耗时最后汇总分析哪个环节最慢。如果要算更长时间段比如两个日期之间差多少天可以先把日期转成时间戳再相减最后除以 86400D1$(date -d 2024-03-01 %s) D2$(date -d 2024-03-14 %s) echo $(( (D2 - D1) / 86400 )) # 输出13这里要注意整除的问题。如果两个时间点不是整天的差距直接除以 86400 会丢掉小数部分。需要精确到小时或分钟的话就分别除以 3600 或 60。3.4 日期运算的边界与陷阱日期运算最容易出问题的地方是跨月、跨年、闰年这些边界情况。我整理了几个典型场景场景表达式可能的问题月末往前推date -d 1 month ago月份长度不同结果可能不是预期日期跨年计算date -d last year闰年 2 月 29 日可能报错时区影响跨时区服务器同一时间戳在不同时区显示不同日期夏令时部分地区某些日期可能不存在或重复注意如果你的脚本要在多台服务器上跑而这些服务器的时区设置不一致那日期计算结果可能对不上。稳妥的做法是在脚本里显式指定时区比如TZAsia/Shanghai date %Y-%m-%d这样不管服务器默认时区是什么输出都一致。4. 实战场景把日期练习用到真实脚本里4.1 日志文件按日期切分与清理这是date最经典的实战场景。假设你有一个每天生成日志的服务日志文件名带日期后缀现在要清理七天前的日志#!/bin/bash LOG_DIR/var/log/myapp CUTOFF$(date -d 7 days ago %Y%m%d) for file in $LOG_DIR/*.log; do FILE_DATE$(basename $file | grep -oE [0-9]{8}) if [ -n $FILE_DATE ] [ $FILE_DATE -lt $CUTOFF ]; then rm -f $file echo 已删除$file fi done这段脚本的核心逻辑是算出七天前的日期字符串然后和文件名里的日期字符串做字典序比较。因为YYYYMMDD格式的字典序和时间序一致所以直接用-lt比较就行不需要转成时间戳。这个技巧在批量处理带日期的文件名时特别好用。4.2 生成带时间戳的备份文件名备份脚本里几乎一定会用到时间戳命名避免覆盖#!/bin/bash BACKUP_DIR/data/backup TIMESTAMP$(date %Y%m%d_%H%M%S) BACKUP_FILE$BACKUP_DIR/db_$TIMESTAMP.sql mysqldump -u user -p database $BACKUP_FILE echo 备份完成$BACKUP_FILE这里用%Y%m%d_%H%M%S而不是%s原因是可读性更好。时间戳虽然紧凑但人看的时候还得换算而20240314_092731一眼就能看出是什么时候备的。如果备份频率很高秒级可能重复可以再加%N纳秒或者用$$进程号做后缀。4.3 判断当前时间段执行不同逻辑有些脚本需要根据当前时间走不同分支比如白天执行全量同步夜间执行增量同步#!/bin/bash HOUR$(date %H) if [ $HOUR -ge 8 ] [ $HOUR -lt 20 ]; then echo 白天模式执行全量同步 # 全量同步逻辑 else echo 夜间模式执行增量同步 # 增量同步逻辑 fi注意%H输出的是两位数字比如08、09。在[ ]里做数值比较时前导零可能导致问题因为某些 shell 会把08当成八进制解析而报错。稳妥的做法是用10#强制十进制或者用$((10#$HOUR))转换。这个坑我在一个定时脚本里踩过当时是早上八点脚本直接报错退出排查了半天才发现是八进制的问题。4.4 计算脚本运行耗时并格式化输出前面提过用时间戳做差算耗时这里给一个更完整的版本把秒数格式化成“X分Y秒”#!/bin/bash START$(date %s) # 模拟耗时操作 sleep 125 END$(date %s) ELAPSED$((END - START)) MIN$((ELAPSED / 60)) SEC$((ELAPSED % 60)) echo 总耗时${MIN}分${SEC}秒这种格式化输出在给非技术同事看的时候特别有用比裸秒数直观得多。如果耗时可能超过一小时再加一层小时计算就行。5. 常见问题与排查技巧实录5.1 时区问题导致日期对不上这是最高频的问题。同一台服务器上date显示的时间和你的预期差几个小时多半是时区设置的问题。排查步骤先看当前时区timedatectl或cat /etc/timezone再看date输出的时区缩写date %Z临时指定时区测试TZAsia/Shanghai date如果确认是时区问题修改系统时区用timedatectl set-timezone Asia/Shanghai。但要注意改系统时区可能影响其他服务生产环境操作前先确认影响范围。5.2 格式串不生效或输出乱码格式串不生效通常有三个原因忘了加、忘了加引号、占位符写错。排查时先把格式串简化到最小比如只留%Y确认能输出后再逐步加回其他占位符。输出乱码则可能是 locale 设置问题LC_ALLC date可以强制用 POSIX locale输出稳定的英文格式。5.3 日期运算结果不符合预期-d表达式的结果和直觉不符时先确认表达式的解析方式。比如date -d 1 month和date -d next month在某些版本里行为不同。稳妥的做法是用具体日期做基准测试date -d 2024-01-31 1 month %Y-%m-%d # 不同版本可能输出 2024-02-29 或 2024-03-02遇到这种不确定性就改用天数计算或者用脚本自己处理月末逻辑。5.4 常见问题速查表问题现象可能原因解决方法输出时间差几小时时区设置不对检查TZ和系统时区格式串原样输出忘了加或引号检查命令写法分钟月份搞混%m和%M写反对照占位符表数值比较报错前导零被当八进制用10#强制十进制日期运算结果偏移月份长度或闰年影响改用天数计算脚本在不同机器结果不同时区或 locale 不一致显式指定TZ和LC_ALL提示写日期相关脚本时养成在脚本开头固定TZ和LC_ALL的习惯比如export TZAsia/Shanghai和export LC_ALLC。这两行能帮你规避掉大部分跨环境不一致的问题属于花小钱办大事。6. 进阶技巧让日期处理更稳更省事6.1 用 date 生成日期序列有时候需要生成一段连续的日期比如做报表要列出最近七天的日期。用循环配合date -d就能实现for i in $(seq 0 6); do date -d $i days ago %Y-%m-%d done这个写法比手写七个日期灵活得多改一下范围就能生成任意长度的序列。如果要做成数组供后续使用可以这样DATES() for i in $(seq 0 6); do DATES($(date -d $i days ago %Y-%m-%d)) done echo ${DATES[]}6.2 处理“上个月第一天”这类需求“上个月第一天”是报表场景里的常见需求用date可以这样算date -d $(date %Y-%m-01) -1 month %Y-%m-01逻辑是先拿到本月第一天再往前推一个月就是上个月第一天。同理“本月最后一天”可以这样date -d $(date -d next month %Y-%m-01) -1 day %Y-%m-%d先拿到下个月第一天再减一天就是本月最后一天。这种“先定位到边界再偏移”的思路比直接算月末要可靠得多因为它不依赖月份长度的假设。6.3 把日期逻辑封装成函数复用如果脚本里多处用到日期计算封装成函数能省很多事#!/bin/bash # 获取 N 天前的日期格式 YYYY-MM-DD days_ago() { local n$1 date -d $n days ago %Y-%m-%d } # 获取当前时间戳 now_ts() { date %s } # 把时间戳格式化为可读时间 fmt_ts() { local ts$1 date -d $ts %Y-%m-%d %H:%M:%S } echo 七天前$(days_ago 7) echo 当前时间戳$(now_ts) echo 格式化$(fmt_ts 1710383251)函数封装的好处是逻辑集中、修改方便而且调用处看起来更清晰。我现在的习惯是只要日期逻辑出现两次以上就立刻抽成函数避免复制粘贴带来的不一致。6.4 日期练习的延伸方向把date用熟之后可以往几个方向继续深入。一个是结合cron做定时任务理解 cron 的时间字段和date的关系另一个是结合find的-mtime参数做文件时间筛选find的时间计算逻辑和date不太一样值得单独研究还有就是处理 ISO 8601 格式、RFC 3339 格式这些标准时间表示在对接外部系统时会用到。我个人在实际操作中的体会是date这个命令的性价比极高——花一两个小时把格式化和-d运算练熟之后写脚本能省下大量查资料的时间。而且它不像有些命令那样参数繁多、学习曲线陡峭核心用法就那么几个练几次就能形成肌肉记忆。真正需要留心的是时区和边界情况这两块踩过坑之后基本就没什么能难住你的了。

相关新闻

苍穹外卖Day09实战:订单状态机、WebSocket推送与超时取消设计

苍穹外卖Day09实战:订单状态机、WebSocket推送与超时取消设计

把苍穹外卖这个项目做到 day09 之前,我一直觉得它和普通的增删改查课设没本质区别:建表、写接口、调页面,一个模块一个模块地堆。但 day09 这一天做的是订单,准确说是“从用户下单到商家接单再到配送完成”的完整订单链路。它第一…

2026/10/18 22:42:47 阅读更多 →
AiPy抢先支持GLM-5:开发者快速接入实战指南

AiPy抢先支持GLM-5:开发者快速接入实战指南

GLM-5 正式发布后,圈子里最快的动作不是刷新闻,而是找接口。过去几年大家都有同一个体感:模型迭代越来越快,真正卡住应用层开发的,往往不是模型能力,而是接入路径。这次 AiPy 在第一时间上架了对 GLM-5 的支…

2026/10/18 22:42:47 阅读更多 →
Java个人博客系统毕设:从环境配置到项目跑通的实操指南

Java个人博客系统毕设:从环境配置到项目跑通的实操指南

简介:基于Java的个人博客系统毕业设计资料包,面向软件工程、计算机等相关专业学生,可作为毕业设计参考和Java Web开发实战案例。资源涵盖项目报告、答辩PPT、源代码、数据库文件及部署教程视频,系统多采用MVC设计模式,…

2026/10/18 22:42:47 阅读更多 →

最新新闻

Android自定义SeekBar:图片背景与图片进度的实现方案与避坑指南

Android自定义SeekBar:图片背景与图片进度的实现方案与避坑指南

简介:面向Android开发者的SeekBar定制方案资源包,以图片替换系统原生样式,解决默认SeekBar外观单一、难以匹配界面整体设计的问题。压缩包内是一个完整的Eclipse工程示例,演示如何继承SeekBar并编写MySeekBar类,在attr…

2026/10/19 2:21:37 阅读更多 →
匹配滤波与脉冲压缩:从信噪比最大化到MATLAB仿真避坑

匹配滤波与脉冲压缩:从信噪比最大化到MATLAB仿真避坑

简介:这是一份面向雷达信号处理、数字信号处理学习者的Matlab仿真与推导资料,核心围绕线性调频(LFM)信号匹配滤波,系统讲解增益和归一化系数的来龙去脉。作者先分别推导信号和白噪声通过匹配滤波后的增益公式&#xff…

2026/10/19 2:21:37 阅读更多 →
基于RK3588的边缘AI婴儿监护系统:多模态融合与工程实践

基于RK3588的边缘AI婴儿监护系统:多模态融合与工程实践

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/19 2:21:37 阅读更多 →
Codex 0.105.0语音编程实测:按住空格说话让AI直接写代码

Codex 0.105.0语音编程实测:按住空格说话让AI直接写代码

作为一个常年在终端里干活的人,我对"命令行工具又更新了"这种消息本来已经麻木了。但这次 Codex 0.105.0 的更新确实让我多看了两眼:按住空格键,对着终端说话,让它直接把代码写出来。听起来像demo噱头,但真正…

2026/10/19 2:21:37 阅读更多 →
专科生论文降AIGC检测全攻略:从查重到AI痕迹的实战方法

专科生论文降AIGC检测全攻略:从查重到AI痕迹的实战方法

查重率10%,AIGC疑似度91%。A同学拿着检测报告坐在我面前时,表情比论文答辩还沉重。导师的话很直接:要么把AI痕迹降下来,要么别进盲审。这不是个例。最近几个月,找我咨询论文降重的人里,专科生比例明显上升&…

2026/10/19 2:21:37 阅读更多 →
PyCharm 安装激活全流程避坑指南:从版本选择到环境配置

PyCharm 安装激活全流程避坑指南:从版本选择到环境配置

简介:面向初学Python编程语言或需要重新配置开发环境的人群,这份PyCharm安装教程以Word文档形式,完整梳理了从获取安装包、安装选项配置到激活授权的整个操作链路。文档采用分步骤讲解,先介绍在浏览器搜索入口找到下载页面&#x…

2026/10/19 2:20:36 阅读更多 →

日新闻

频率跟踪型PWM电源设计:臭氧发生器谐振点漂移与软开关实现

频率跟踪型PWM电源设计:臭氧发生器谐振点漂移与软开关实现

简介:本资源为电源技术方向的学术研究文档,聚焦介质阻挡放电型臭氧发生器电源的频率跟踪型PWM控制策略,面向电力电子、高压电源及臭氧应用领域的科研人员与工程技术人员。针对负载呈容性、等效电容随外加电压升高而增大、谐振频率随之漂移的难…

2026/10/19 0:00:47 阅读更多 →
Vibe Coding 遇上 TaoToken:把开发者思维圣殿的灵感流接入统一 Key 通道

Vibe Coding 遇上 TaoToken:把开发者思维圣殿的灵感流接入统一 Key 通道

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/19 0:00:47 阅读更多 →
HundredCV-Chat话题建模实战教程:利用4,871个内置话题标签构建主题分析系统

HundredCV-Chat话题建模实战教程:利用4,871个内置话题标签构建主题分析系统

【免费下载链接】HundredCV-Chat 项目地址: https://ai.gitcode.com/hf_mirrors/Jax-dan/HundredCV-Chat 点击查看 免费下载 HundredCV-Chat 是一个由 100 位青年简历数据开发而来的中文多轮对话数据集,共包含 24,750 组日常闲聊对话和 4,871 个话题标签…

2026/10/19 0:00:47 阅读更多 →

周新闻

基于GMM的语音识别系统原理与MATLAB实现详解

基于GMM的语音识别系统原理与MATLAB实现详解

说到基于高斯混合模型(GMM)的语音识别系统,很多人第一反应就是一堆数学公式,觉得门槛很高。但如果你真的在MATLAB里把它落地跑通,会发现核心其实就是三件事:把声音变成特征向量,用GMM给每个类别…

2026/10/18 0:00:55 阅读更多 →
数字图像处理入门:反白、灰度化、调色板修改与导出txt实践

数字图像处理入门:反白、灰度化、调色板修改与导出txt实践

数字图像处理这四个字听起来挺唬人,但落到具体操作上,无非就是让计算机按你的想法“摆弄”像素。我在一个模拟项目X里用了一套特别经典的基础处理流程:对图像做反白、改调色板、彩色转灰度,最后把像素数据导出成txt文件。单看每一…

2026/10/18 0:00:55 阅读更多 →
机器人大脑技术盘点:具身智能的感知、决策与数据闭环

机器人大脑技术盘点:具身智能的感知、决策与数据闭环

如果你的信息流最近也天天刷到“机器人大脑”这个词,你会发现一个很有意思的现象:每个人说的“大脑”根本不是同一个东西。有人指的是大语言模型,有人指的是运动控制系统,还有人指的是能理解物理世界的端到端模型。在2026年这个时…

2026/10/19 1:30:52 阅读更多 →

月新闻

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/18 0:55:02 阅读更多 →
Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/17 17:22:31 阅读更多 →
黑夜航拍船只数据集训练YOLOV5模型全流程解析

黑夜航拍船只数据集训练YOLOV5模型全流程解析

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/18 12:16:16 阅读更多 →