shell Bash将时间戳增加1天,从小时中减去1天

bq3bfh9z  于 2023-04-21  发布在  Shell
关注(0)|答案(5)|浏览(290)

我有一个bash脚本,它应该将时间戳增加1天,以从时间戳中回显接下来的5天,但是当它运行时,它产生了错误的输出,并减去了一个小时。
脚本

#!/bin/bash

TIME_STAMP="2023-06-03 06:21:33"

for i in {1..5}
do
    NEXT_DATE=$(date "+%Y-%d-%m %H:%M:%S" -d "$TIME_STAMP +$i day")
    echo $NEXT_DATE
done

输出

2023-04-06 06:21:33
2023-04-06 05:21:33
2023-04-06 04:21:33
2023-04-06 03:21:33
2023-04-06 02:21:33

据我所知,日期格式是正确的,所以我完全不知道为什么它不能正常工作。如果有更简单的方法来做到这一点,我很乐意听到它!

tjvv9vkg

tjvv9vkg1#

问题是日期字符串被拆分,而date只根据时间进行计算。
解决方法是拆分时间,然后在生成的日期之后将其添加回去。

for i in {1..5}; do
     NEXT_DATE=$(date "+%Y-%d-%m %H:%M:%S" -d "${TIME_STAMP% *} +$i days ${TIME_STAMP#* }")
     echo "$NEXT_DATE"
done

将输出捕获到一个变量中,这样你就可以echo了,这是一个无用的echo,但我想你希望这个变量在你的真实的用例中有更多的用途。
还要注意date -d是不可移植的;这将在Linux上工作,但在许多其他平台上不工作。

rfbsl7qr

rfbsl7qr2#

字符串解析为:

  • +$i -时区,格式为+HH
  • day -添加一天

添加一个+00,使date将时区解析为UTC。

$ for i in {1..5}; do NEXT_DATE=$(date "+%Y-%d-%m %H:%M:%S" -d "$TIME_STAMP +00 +$i day"); echo $NEXT_DATE; done
2023-04-06 08:21:33
2023-05-06 08:21:33
2023-06-06 08:21:33
2023-07-06 08:21:33
2023-08-06 08:21:33

或使用您当前的时区偏移:

$ tz=$(date +'%z')
$ for i in {1..5}; do NEXT_DATE=$(date "+%Y-%d-%m %H:%M:%S" -d "$TIME_STAMP $tz +$i day"); echo $NEXT_DATE; done
2023-04-06 06:21:33
2023-05-06 06:21:33
2023-06-06 06:21:33
2023-07-06 06:21:33
2023-08-06 06:21:33
sqougxex

sqougxex3#

我认为@KamilCuk的答案是正确的方法,如果你打算使用date,但这里有一个替代方案,假设你不关心DST:

$ cat tst.sh
#!/usr/bin/env bash

this_time_stamp='2023-06-03 06:21:33'

for i in {1..5}
do
    this_date="${this_time_stamp% *}"
    this_time="${this_time_stamp#* }"
    next_time_stamp="$(date '+%Y-%d-%m' -d "$this_date +$i day") $this_time"
    echo "$next_time_stamp"
done
$ ./tst.sh
2023-04-06 06:21:33
2023-05-06 06:21:33
2023-06-06 06:21:33
2023-07-06 06:21:33
2023-08-06 06:21:33

请参阅Correct Bash and shell script variable capitalization了解我为什么将变量名改为小写。
我强烈建议你不要使用YYYY-DD-MM而不是YYYY-MM-DD或类似的格式,因为之后很难做任何事情,例如在一个范围内排序或搜索。

woobm2wo

woobm2wo4#

使用带有 * 核心模块 * 的Perl(默认安装),没有日期字符串的“作弊”,我猜是最便携和最强大的解决方案。
wink to @艾德;)

perl -MTime::Piece -MTime::Seconds -sE '
    foreach my $i (1..5) {
        my $d = Time::Piece->strptime($mydate, "%Y-%d-%m %H:%M:%S");
        ($dow, $month, $dom, $hour, $year) = split / +/, $d +$i*ONE_DAY;
        my $dateold = Time::Piece->strptime(
            "$dow $month $dom $year $hour",
            "%a %b %d %Y %H:%M:%S");
        say $dateold->strftime("%Y-%d-%m %H:%M:%S");
    }
' -- -mydate='2023-06-03 06:21:33'
2023-07-03 06:21:33
2023-08-03 06:21:33
2023-09-03 06:21:33
2023-10-03 06:21:33
2023-11-03 06:21:33
kwvwclae

kwvwclae5#

简单,而不是本地时区,我们可以使用date-u选项的UTC区,添加'0000'在输入时区的UTC转换

#!/bin/bash
UTC="2023-06-03 06:21:33+0000"
for days in {1..5}
do
    DATE_NEXT=$(date -u "+%Y-%m-%d %H:%M:%S" -d "$UTC +$days day")
    echo $DATE_NEXT
done

output:

2023-06-04 06:21:33
2023-06-05 06:21:33
2023-06-06 06:21:33
2023-06-07 06:21:33
2023-06-08 06:21:33

相关问题