在Linux上使用bash获取昨天的日期,DST-safe

Ike*_*ker 142 linux bash

我有一个在Linux上运行的shell脚本,并使用此调用以YYYY-MM-DD格式获取昨天的日期:

date -d "1 day ago" '+%Y-%m-%d'
Run Code Online (Sandbox Code Playgroud)

它大部分时间都可以工作,但是当脚本在昨天早上运行时,2013-03-11 0:35 CDT它返回"2013-03-09"而不是"2013-03-10".

大概是夏令时(从昨天开始)应该归咎于.我猜的方式"1 day ago"来实现它减去24小时,前24小时2013-03-11 0:35 CDT2013-03-09 23:35 CST,这导致的结果"2013-03-09".

那么,什么是一个很好的DST安全方式来获取昨天在Linux上使用bash的日期?

tin*_*ink 239

我认为这应该有效,无论你多久经营一次......

date -d "yesterday 13:00" '+%Y-%m-%d'
Run Code Online (Sandbox Code Playgroud)

  • @null - 与分配任何其他shell命令的输出的方式相同.变量= $(日期-d"昨天13:00"'+%Y-%m-%d')... (6认同)
  • 对于 GNU 日期:`date -d 昨天 13:00 -I` (2认同)
  • @NicolasRaoul:不保证; 但是这是一个广泛遵循的惯例,将其安排到清晨.另一方面,IIRC没有地方可以在当地中午附近进行转换.因此,"1300J永远不会在DST边界上"是一个合理的假设*. (2认同)

小智 49

Mac OSX下的Bash略有不同.

对于昨天

echo `date -v-1d +%F`
Run Code Online (Sandbox Code Playgroud)

对于上周

echo `date -v-1w +%F`
Run Code Online (Sandbox Code Playgroud)

  • 你的意思是'日期'是不同的. (10认同)
  • 如果有兴趣在OSX中使用GNU样式,你也可以使用`gdate`,在homebrew的`coreutils`包中可用. (8认同)

per*_*eal 11

这也应该有效,但可能太多了:

date -d @$(( $(date +"%s") - 86400)) +"%Y-%m-%d"
Run Code Online (Sandbox Code Playgroud)

  • 如果你需要处理不支持 `yesterday` 语法的 Mac OS X `date`,就需要这样的东西...... (2认同)
  • 当我使用“BusyBox v1.31.1”时,这是一个有效的解决方案 (2认同)

leo*_*loy 8

如果您确定脚本在一天的前几个小时运行,您可以简单地执行

  date -d "12 hours ago" '+%Y-%m-%d'
Run Code Online (Sandbox Code Playgroud)

顺便说一句,如果脚本每天在 00:35 运行(通过 crontab?),您应该问问自己,如果 DST 更改落在那个小时内会发生什么;脚本无法运行,或在某些情况下运行两次。现代的实现cron相当聪明在这方面,虽然。


sur*_*oni 8

date -d "yesterday" '+%Y-%m-%d'
Run Code Online (Sandbox Code Playgroud)

稍后使用它:

date=$(date -d "yesterday" '+%Y-%m-%d')
Run Code Online (Sandbox Code Playgroud)

  • 虽然此代码可以解决 OP 的问题,但最好包含有关代码如何解决 OP 问题的解释。这样,未来的访问者可以从您的帖子中学习,并将其应用到他们自己的代码中。SO 不是编码服务,而是知识资源。高质量、完整的答案强化了这一想法,并且更有可能获得赞成。这些功能,加上所有帖子必须独立的要求,是 SO 作为平台的一些优势,使我们有别于论坛。您可以编辑以添加附加信息和/或用源文档补充您的解释。 (4认同)

Wal*_*r A 5

这是一个也适用于 Solaris 和 AIX 的解决方案。

操纵时区可以改变几个小时的时钟。由于夏令时,24 小时前可以是今天或前天。

你确定昨天是 20 或 30 小时前。哪一个?嗯,不是今天的最新的。

echo -e "$(TZ=GMT+30 date +%Y-%m-%d)\n$(TZ=GMT+20 date +%Y-%m-%d)" | grep -v $(date +%Y-%m-%d) | tail -1
Run Code Online (Sandbox Code Playgroud)

bash 需要使用 echo 命令中使用的 -e 参数,但不适用于 ksh。在 ksh 中,您可以使用没有 -e 标志的相同命令。

当您的脚本将在不同环境中使用时,您可以使用 #!/bin/ksh 或 #!/bin/bash 启动脚本。您还可以用换行符替换 \n:

echo "$(TZ=GMT+30 date +%Y-%m-%d)
$(TZ=GMT+20 date +%Y-%m-%d)" | grep -v $(date +%Y-%m-%d) | tail -1
Run Code Online (Sandbox Code Playgroud)

  • 非常 hacky,但它也适用于 Darwin 上的 zsh。你刚刚救了我一把叉子,伙计。:) (2认同)

Dan*_*ard 5

您可以使用

date -d "30 days ago" +"%d/%m/%Y"
Run Code Online (Sandbox Code Playgroud)

要获取 30 天前的日期,同样您可以用 x 天数替换 30