在Shell脚本中使用YYYY-MM-DD日期格式

1487

我在bash shell脚本中尝试使用$(date),但是我想要的日期格式是YYYY-MM-DD
我该如何获取?


15
评论长度必须至少为15个单词。date -I - abc
26
确实,date -I 就是你需要的全部内容。我花了好几年才偶然发现这个命令。 - Sridhar Sarnobat
6
date -I 只适用于 Linux 上的 GNU 工具,并不适用于 macOS/ BSD。安装 brew 后,运行 brew install coreutils 即可使用 gdate -I 命令。 - ssc
18个回答

2268
在bash(>=4.2)中,最好使用printf内置的日期格式化程序(bash的一部分),而不是外部的date(通常是GNU date)。请注意,在Cygwin中调用子shell存在性能问题,这是由于Windows上较慢的fork()调用所致。
因此:
# put current date as yyyy-mm-dd in $date
# -1 -> explicit current date, bash >=4.3 defaults to current time if not provided
# -2 -> start time for shell
printf -v date '%(%Y-%m-%d)T\n' -1 

# put current date as yyyy-mm-dd HH:MM:SS in $date
printf -v date '%(%Y-%m-%d %H:%M:%S)T\n' -1 

# to print directly remove -v flag, as such:
printf '%(%Y-%m-%d)T\n' -1
# -> current date printed to terminal

在bash中(<4.2):
# put current date as yyyy-mm-dd in $date
date=$(date '+%Y-%m-%d')

# put current date as yyyy-mm-dd HH:MM:SS in $date
date=$(date '+%Y-%m-%d %H:%M:%S')

# print current date directly
echo $(date '+%Y-%m-%d')

其他可用的日期格式可以从date man pages(供外部非bash特定命令使用)查看:

man date

6
每月的前几天,我得到的是“2012-07-1”,这不是OP所要求的内容。 - DerMike
6
这对我有效。手册建议月初为01而非1(例如:2012-07-01)。 - Bob Kuhar
46
DATE=$(date +%d-%m-%Y" "%H:%M:%S); 这行代码的意思是获取当前时间并用指定的格式进行格式化,将结果保存在变量DATE中。 "What I ended up after."这句话不太清楚上下文,需要更多的信息才能给出准确的翻译。 - JacopKane
9
我还没有检查这些快捷方式的普及程度,但在某些发行版中,您可以使用“+%F %T”作为“+%Y-%m-%d %H:%M:%S”的快捷方式。请注意,_一些文件系统_(咳咳**HFS)会将:转换为/,导致您得到一个像2016-09-15 11/05/00这样非常令人困惑的字符串。 - beporter
37
本千年中任何符合 POSIX 标准的 Shell 脚本首选语法是 date=$(date) 而非 date=\date``。此外,不要使用大写字母来定义您的私有变量;大写字母的变量名已保留给系统使用。 - tripleee
显示剩余17条评论

514

尝试: $(date +%F)

%F选项是%Y-%m-%d的别名


17
日期命令的 man 手册中写道: %F 表示完整日期,与 %Y-%m-%d 相同,因此这只是对所接受答案的更紧凑表示法。 - Håvard Geithus
1
这个答案在 zsh 中同样适用。 - Glen K

153
你可以像这样做:
$ date +'%Y-%m-%d'

迄今为止,最容易记住和最可配置的方法...越简单越好! - undefined

85
$(date +%F)

输出

2018-06-20

或者如果您也需要时间:

$(date +%F_%H-%M-%S)
可以用来移除中间的冒号(:)。 输出。
2018-06-20_09-55-58

3
感谢您额外的时间 - OP可能没有提问,但我相信大多数搜索此内容的人都会感兴趣! - Adam Hughes
5
%T 也是 %H:%M:%S 的有用别名。 - mgutt
谢谢 @mgutt!最后我选择了 $(date '+%F_%T') - Teun M.

56
你需要的是ISO 8601标准日期格式,如果你有GNU date(或任何比1988年更现代的日期命令),只需执行以下命令:$(date -I)

10
我有一台较新的(>1988)Mac OS X电脑,但是“date -I”无法使用。通过使用brew安装GNU coreutils(它使用前缀'g'),gdate -I可以正常工作。 - Joel Purra
4
奇怪,我找不到GNU date的文档中有-I选项的说明,但它确实相当于date +%F - chepner
4
OS X 通常是一个 GPL v3 荒地,因此他们可能只是没有最近更新日期或 BASH。 - Indolering
1
我喜欢这个选项,因为在 cron 中不需要转义“%”。 - simlev

27
date -d '1 hour ago' '+%Y-%m-%d'

输出结果会是2015-06-14


5
有几个错误,显然这会给出在 00:00 和 01:00 之间的错误日期,此外,你最后还有一个“%”。 - Gerhard Burger
它不是真的。应该像这样稀疏单引号。 - Beyhan Gul

24

最近的Bash(版本≥4.2)中,您可以使用内置的printf命令和格式修饰符%(strftime_format)T

$ printf '%(%Y-%m-%d)T\n' -1  # Get YYYY-MM-DD (-1 stands for "current time")
2017-11-10
$ printf '%(%F)T\n' -1  # Synonym of the above
2017-11-10
$ printf -v date '%(%F)T' -1  # Capture as var $date

printfdate快得多,因为它是Bash内置命令,而date是外部命令。

此外,printf -v date ...date=$(printf ...)更快,因为它不需要fork一个子shell。


5
作为2019年的一份说明,如果您已经在bash脚本中使用此命令,则它比 date 命令要快得多,因为它不需要加载任何额外的库。(*在我的Linux服务器上,我测量出在1000次迭代中,速度差异约为160倍) - timtj
@timtj 感谢您指出这一点!我在答案中添加了一些关于速度的注释。 - wjandrea
1
我希望我能够为关于 printf -v date 不派生子 shell 的评论加上 +5。非常好的信息!! - timtj
通常我使用日期,因为我还需要逐个增加一些日期。printf能进行日期算术运算吗? - Merlin
1
@Merlin 我不这么认为。 - wjandrea

18

我使用以下表述:

TODAY=`date -I`
echo $TODAY

请查看 date 命令的 man 手册,其中包括许多其他有用的选项:

man date

2
这个答案似乎等同于另一个答案,实际上使用了另一种语法$(...)进行命令替换; 有关详细信息,请参见例如GreyCatBashFAQ#082 - ErikMD

12

如果您想将年份以两位数格式表示,例如17而不是2017,请执行以下操作:

DATE=`date +%d-%m-%y`

10
我采用下面的方法。感谢所有提供方法和答案的人。
ubuntu@apj:/tmp$ datevar=$(date +'%Y-%m-%d : %H-%M')
ubuntu@apj:/tmp$ echo $datevar
2022-03-31 : 10-48

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接