关于bash:今天的日期,在shell脚本中减去X天

Today's date, minus X days in shell script

我需要创建三个变量,每个变量表示今天日期的年、月和日,减去x天数。对于这个问题,我将随机选择天数:222。

所以如果:

1
2
3
TodayYear=`date +%Y`
TodayMonth=`date +%m`
TodayDay=`date +%d`

我要的是在这之前222天。

1
2
3
222days_before_TodayYear=???
222days_before_TodayMonth=???
222days_before_TodayDay=???

编辑:需要222个工作日,而不是222个正常工作日。


是GNU date

1
2
3
date_222days_before_TodayYear=$(date --date="222 days ago" +"%Y")
date_222days_before_TodayMonth=$(date --date="222 days ago" +"%m")
date_222days_before_TodayDay=$(date --date="222 days ago" +"%d")

在BSD date

如果你使用的是FreeBSD的X或以下,使用BSD的日期是不同的。因为从GNU日期:

1
2
3
date_222days_before_TodayYear=$(date -j -v-222d +"%Y")
date_222days_before_TodayMonth=$(date -j -v-222d +"%m")
date_222days_before_TodayDay=$(date -j -v-222d +"%d")

手册页日期:BSD源码

注意:

在许多其他的语言和bash无法启动,你的变量名和数值字符,所以我prefixed date_他们与你。

更新:新的要求使用第二天的工作而经常222 222天。

(假设不考虑:法定假期,因为这只会远超出范围,你可以帮助我与在外壳脚本)

考虑工作日:222

  • 每周工作5天,这是floor(222/5) == 44 weeks
  • 44 weeks * 7 days per week == 308 days
  • 额外的222 % 5 == 2leftover:天
  • 因此,222 working days == 310 regular days

但是,有一个抓的!如果经常是数天或7308一些多),然后我们将有一个好的多,因为任何从8月7日工作日工作日仍然是。所以我们需要考虑今天是否是星期一或者星期二:

  • 如果今天是星期一,我们得到我们想要的地方(星期六星期四
  • 如果今天是星期二,我们得到我们想要的星期日,星期五(D)

所以你看,我们需要一个额外的2天,如果更多的偏移是指今天的星期一或星期二,让’s find out:那我们先在í

1
2
3
4
5
6
7
8
9
10
11
12
13
14
#!/bin/bash

# Use 310 days as offset instead of 222
offset=310
# Find locale's abbreviated weekday name (e.g., Sun)
today=$(date -j +"%a")
# Check for Mon/Tue
if [["$today" =="Mon" ]] || [["$today" =="Tue" ]]; then
     offset=$((offset+2))
fi

date_222_working_days_before_TodayYear=$(date -j -v-${offset}d +"%Y")
date_222_working_days_before_TodayMonth=$(date -j -v-${offset}d +"%m")
date_222_working_days_before_TodayDay=$(date -j -v-${offset}d +"%d")

这就是它应该的= =)

  • 我得到了date: illegal date format-我想知道我是否使用了错误的引号类型(我从这里复制并粘贴,但脚本出错)。有什么想法吗?
  • @用户1644609尝试更新的答案,但之前的引号不应该是错误。您的问题被标记为bash,但您知道您使用的是哪种版本的shell吗?
  • 谢谢@sampson chen-我已经尝试过你的更新,但是现在我没有得到illegal date format,而是得到illegal time format(然后是用法说明)。我的bash版本是:GNU bash, version 3.2.48(1)-release (x86_64-apple-darwin12) Copyright (C) 2007 Free Software Foundation, Inc.
  • @用户1644609:编辑了我的答案-尝试最新版本-这应该有效
  • 现在得到这个错误:date: illegal option -- -(然后是用法说明)
  • @用户1644609:在终端提示下输入date --date="222 days ago" +"%Y"是否可以?
  • @最初不是,我是在一个脚本中做的,但是当我在终端提示下复制并粘贴你最后的评论时,我又得到了非法选项。
  • @谢勒-谢谢你的提示!
  • @用户1644609:如果您使用的是OS X,请参阅更新后的答案-进行了一些挖掘,我认为这是darwin的正确语法(使用-j -v-222d指定您不设置系统时间,并且您希望在222天前调整到负)。
  • @陈先生-我还是不能让它工作。我在达尔文收到的使用说明是:usage: date [-jnu] [-d dst] [-r seconds] [-t west] [-v[+|-]val[ymwdHMS]] ... [-f fmt date | [[[mm]dd]HH]MM[
    1
    2
    3
    4
    yy][.ss]] [+format] </wyn>。</li><li>@用户1644609您是否像在最新版本中那样使用了<wyn>-j -v-222d</wyn>?</li><li>抱歉,我是在您更新时评论的。最新版本有效!我能问一下我是否要换成Ubuntu/Fedora(我计划明年换),你的第一个版本可以用吗?</li><li>@用户1644609 Huzzah,它工作了!是的,这是正确的,因为我相信Ubuntu和Fedora都是GNU。</li><li>令人惊叹的!再次感谢!D</li><li>@陈先生-刚刚意识到我的实际需求和我的问题不同:(我不需要222天前…)我需要222个工作日之前(美国工作日)。哎哟!我想这不是一个容易的方法!</li><li>@用户1644609我考虑了一下,它比你在一些推论的帮助下想的更可行;检查更新后的答案=)</li><li>@陈先生,非常感谢。太棒了。我没想到,所以我在做一个变通方案。在这两种情况下(工作日或正常日),我需要代表1月为0,2月为1(或01),3月为2(或02),等等……我试过了:<wyn>MONTHS200=$(date -j -v-320d -v-1m +"%m") if ${MONTHS200}=01; then   ${MONTH200}=0 else  ${MONTHS200}=${MONTH200} fi </wyn>,但我得到了错误<wyn>.&#47;update_newdateformat.sh: line 20: 12=01: command not found .&#47;update_newdateformat.sh: line 23: 12=: command not found</wyn>。<wyn>-v-1m</wyn>在除1月外的所有月份都有效,因为它是12,而不是0。</li><li>@用户1644609我将在stackoverflow上开始一个单独的问题,因为您现在描述的是变量赋值/比较语法的问题。当你把它拿出来的时候就指给我。</li><li>@谢谢你,sampson,在这里:stackoverflow.com/questions/13535871/&hellip;</li><li>伟大的!在OSX上工作</li></ul>[/collapse]</div><hr><p>你可以得到精确的日期后,在从过去的bash</p>[cc lang="bash"]Number=222
    current_date=$(date +%Y%m%d)
    past_date=$(date -d"$current_date - $Number days" +%Y%m%d)
    echo"$current_date\t$past_date"

    希望这帮助!


    1
    date '+%Y' --date='222 days ago'

    1
    2
    3
    4
    epoch=$(( `date '+%s'` - ( 24 * 60 * 60 * 222 ) ))
    year=`date -d"@$epoch" '+%Y'`
    month=`date -d"@$epoch" '+%m'`
    day=`date -d"@$epoch" '+%d'`

    这样的戏法。

    • 当我这样做时,控制台不会返回任何错误,但它只是说:usage: date [-jnu] [-d dst] [-r seconds] [-t west] [-v[+|-]val[ymwdHMS]] ... [-f fmt date | [[[mm]dd]HH]MM[
      1
      2
      3
      yy][.ss]] [+format]</wyn></li></ul>[/collapse]</div><hr><p>我会说,更容易的解决方案将是</p>[cc lang="bash"]222days_before_TodayYear = $(date -v -222d +%Y)
      222days_before_TodayMonth = $(date -v -222d +%m)
      222days_before_TodayDay = $(date -v -222d +%d)