【问题标题】:Today's date, minus X days in shell script今天的日期,在 shell 脚本中减去 X 天
【发布时间】:2012-11-12 02:07:59
【问题描述】:

我需要为今天的日期创建三个变量,分别代表年、月和日,减去 X 天。对于这个问题,我会随机选择天数:222。

如果:

TodayYear=`date +%Y`
TodayMonth=`date +%m`
TodayDay=`date +%d`

我想要的是在此之前的 222 天。

222days_before_TodayYear=???
222days_before_TodayMonth=???
222days_before_TodayDay=???

编辑:需要 222 个工作天而不是 222 个常规天。

【问题讨论】:

    标签: bash sh


    【解决方案1】:
    date '+%Y' --date='222 days ago'
    

    【讨论】:

      【解决方案2】:

      对于 GNU date

      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:

      如果您使用的是 OS X 或 FreeBSD,请改用以下内容,因为 BSD 日期与 GNU 日期不同:

      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 date manual page

      注意:

      bash 和许多其他语言中,变量名不能以数字字符开头,因此我为它们添加了date_ 前缀。


      第二次更新: 新要求 - 使用 222 个工作日而不是 222 个正常工作日:

      假设:不考虑法定假日,因为这远远超出了我在 shell 脚本中可以帮助您的范围:)

      考虑 222 个工作日:

      • 每周5个工作日,即floor(222/5) == 44 weeks
      • 44 weeks * 7 days per week == 308 days
      • 剩余天数:222 % 5 == 2
      • 因此222 working days == 310 regular days

      但是,有一个问题!如果常规天数是3087 的某个倍数,那么我们就可以了,因为从工作日开始的 7 天前的任何倍数仍然是工作日。所以我们需要考虑今天是星期一还是星期二:

      • 如果今天是星期一,我们会在我们想要星期四的地方到达星期六
      • 如果今天是星期二,我们会在希望星期五的地方得到星期天

      所以你看,如果今天是星期一或星期二,我们需要额外的 2 天偏移;所以让我们在继续之前先找出答案:

      #!/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 - 我想知道我是否使用了错误类型的引号(我从这里复制并粘贴,但该脚本出错了)。有什么想法吗?
      • @user1644609 尝试更新的答案,但之前的引号不应该是错误。你的问题被标记为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.
      • @user1644609:编辑了我的答案 - 试试这个应该工作的最新版本
      • 立即获取此错误:date: illegal option -- -(然后是使用说明)
      【解决方案3】:
      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[[cc]yy][.ss]] [+format]
      【解决方案4】:

      您可以从 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"
      

      希望这会有所帮助!

      【讨论】:

        【解决方案5】:

        我会说更简单的解决方案是

        222days_before_TodayYear = $(date -v -222d +%Y)
        222days_before_TodayMonth = $(date -v -222d +%m)
        222days_before_TodayDay = $(date -v -222d +%d)
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2012-04-17
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多