【问题标题】:How can I get the 1st and last date of the previous month in a Bash script?如何在 Bash 脚本中获取上个月的第一个和最后一个日期?
【发布时间】:2015-01-13 10:41:37
【问题描述】:

我已经安排了一个 Bash 脚本在本月 1 日运行,但我需要在其中创建 2 个变量,其中包含上个月的第一个和最后一个日期,无论它们是什么。

是否可以只使用 Bash 来做到这一点?

【问题讨论】:

  • 这里的大多数(目前所有)答案都需要 GNU date,因此基本上假设是 Linux。有几乎重复的问题展示了如何使用 POSIX / BSD / Mac date
  • 参见例如stackoverflow.com/questions/13168463/… 被标记为 linux,但有几个针对相关问题的便携式解决方案。

标签: bash shell


【解决方案1】:

与某些答案不同,这将适用于本月的 31 日和其他任何一天。我用它来输出unix时间戳,但输出格式很容易调整。

first=$(date --date="$(date +'%Y-%m-01') - 1 month" +%s)
last=$(date --date="$(date +'%Y-%m-01') - 1 second" +%s)

示例(今天的日期是 2019 年 2 月 14 日):

echo $first $last

1546300800 1548979199

要以其他格式输出,请将最终的 +%s 更改为其他格式,例如 +%Y-%m-%d 或省略您区域设置中的默认格式。

如果需要,您还可以像这样备份任意月数:

    # variable must be >= 1
    monthsago=23
    date --date="$(date +'%Y-%m-01') - ${monthsago} month"
    date --date="$(date +'%Y-%m-01') - $(( ${monthsago} - 1 )) month - 1 second"

示例输出(今天的日期是 2019 年 2 月 15 日):

2017 年 3 月 1 日星期三 00:00:00 UTC
2017 年 3 月 31 日星期五 23:59:59 UTC

【讨论】:

  • 这需要 GNU date
【解决方案2】:

这可以用两行来完成,调整日期格式以适应。

START_LAST_MONTH=$(date "+%F" -d "$(date +'%Y-%m-01') -1 month")
END_LAST_MONTH=$(date "+%F" -d "$START_LAST_MONTH +1 month -1 day");

#Test Code
echo START_LAST_MONTH=$START_LAST_MONTH
echo END_LAST_MONTH=$END_LAST_MONTH

跑步给出:

START_LAST_MONTH=2018-09-01
END_LAST_MONTH=2018-09-30

边界测试

 for TEST_DATE in 2018-03-31 2018-12-31 2019-01-01
 do
      START_LAST_MONTH=$(date "+%F" -d "$(date -d $TEST_DATE +'%Y-%m-01') -1 month")
      END_LAST_MONTH=$(date "+%F" -d "$START_LAST_MONTH +1 month -1 day");
      echo TEST_DATE=$TEST_DATE, START_LAST_MONTH=$START_LAST_MONTH, END_LAST_MONTH=$END_LAST_MONTH
 done

输出

 TEST_DATE=2018-03-31, START_LAST_MONTH=2018-02-01, END_LAST_MONTH=2018-02-28
 TEST_DATE=2018-12-31, START_LAST_MONTH=2018-11-01, END_LAST_MONTH=2018-11-30
 TEST_DATE=2019-01-01, START_LAST_MONTH=2018-12-01, END_LAST_MONTH=2018-12-31

【讨论】:

  • 尽管我很喜欢这个工作(我不喜欢嵌套日期命令的想法来完成这样一个平凡的任务),但请注意,此代码将在任何一个月的 31 日和三月的最后几天(取决于闰年)。例如。 date "+%Y-%m-01" -d "31 May 2019 -1 Month" = 2019-05-01。修正此答案将使其与所有其他正确答案相同。
  • 评论已过期。
【解决方案3】:

由于月份的长度不同,我认为最可靠的方法是将日历偏移量从当月的第一天开始,而不是任何其他任意日期,然后减去天数...

在下面的 sn-p 中,您可以将 $TODAY 设置为您需要的任何日期,$LAST_MONTH_START$LAST_MONTH_END 最终将包含上个月的开始和结束日期:

TODAY=$(date '+%F') # or whatever YYYY-MM-DD you need
THIS_MONTH_START=$(date -d "$TODAY" '+%Y-%m-01')
LAST_MONTH_START=$(date -d "$THIS_MONTH_START -1 month" '+%F')
LAST_MONTH_END=$(date -d "$LAST_MONTH_START +1 month -1 day" '+%F')

【讨论】:

    【解决方案4】:

    无论您在哪一天执行日期命令,都可以尝试以下日期命令以获得上个月的第一天和最后一天

    Firstday=`date -d "-1 month -$(($(date +%d)-1)) days"`
    Lastday=`date -d "-$(date +%d) days"`
    

    【讨论】:

    • 这需要 GNU date 并且不可移植(尤其是 Mac / *BSD date 不同)。
    【解决方案5】:

    测试

    first=`date -d "02/05/2018" +"%Y%m01"`
    last=`date -d "02/05/2018 + 1 month-5 day" +"%Y%m%d"`
    

    示例

    RUNDATE="20180207"
    y="${RUNDATE:0:4}"
    m="${RUNDATE:4:2}"
    d="${RUNDATE:6:2}"
    RUNDATE_START=`date -d "$m/$d/$y" +"%Y%m01"`
      RUNDATE_END=`date -d "$m/$d/$y + 1 month - $d day" +"%Y%m%d"`
    

    结果

    20180201<br/>
    20180228
    

    【讨论】:

    • 欢迎来到 StackOverflow。只有代码的答案往往会被标记为“低质量”并被删除。请在您的代码旁边提供一些基本解释。
    【解决方案6】:

    例子:

    #!/bin/bash
    for monthsback in 1 2 3 4 5 6 7 8 9 10 11 12
    do
        monthsfwd=`expr $monthsback - 1`
        startdate=`date -d "-${monthsback} month -$(($(date +%d)-1)) days" +%Y-%m-%d`
        enddate=`date -d "-$(date +%d) days -${monthsfwd} month" +%Y-%m-%d`
        echo "$monthsback month(s) ago:"
        echo $startdate
        echo $enddate
        echo ""
    done
    

    将输出 (monthsback) 几个月前的第一天和最后一天:

    2016-06-01 - 2016-06-30

    2016-05-01 - 2016-05-31

    下面将设置两个变量分别为上个月的开始和结束:

    #!/bin/bash
    monthsback=1
    monthsfwd=`expr $monthsback - 1`
    startdate=`date -d "-${monthsback} month -$(($(date +%d)-1)) days" +%Y-%m-%d`
    enddate=`date -d "-$(date +%d) days -${monthsfwd} month" +%Y-%m-%d`
    

    【讨论】:

    • 如果你在 Bash 上,使用 expr 进行简单的整数运算是错误的。使用内置算法,如monthsfwd=$((monthsback - 1))
    【解决方案7】:

    如果您在每月的第一天执行此操作,那么您可以使用类似

    first=$(date --date='-1 month')
    last=$(date --date='-1 day')
    

    但如果你在另一个日期运行,那么我想你需要从一个已知的参考日期开始。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2012-05-29
      • 2013-06-23
      • 1970-01-01
      • 2018-01-30
      • 1970-01-01
      • 2021-03-22
      • 1970-01-01
      相关资源
      最近更新 更多