如何让bash date脚本返回相对于非当前时间的星期几?

时间:2021-11-11 07:11:42

Using bash date, I can get it to return a day of the week relative to the current time.

使用bash日期,我可以让它返回相对于当前时间的一周中的某一天。

date --d='last Sunday' #Returns date of the Sunday before today

I can also get it to return a day relative to some other date

我还可以让它返回相对于其他日期的一天

date --d='02/1/2012 -2 days' #Returns date two days before Feb. 1, 2012

but how can I get it to return the day of the week relative to some non-current time? What I want to do is:

但是,相对于某些非当前时间,我怎样才能让它返回星期几呢?我想做的是:

date --d='Sunday before 02/1/2012' #Doesn't work! I want Sunday before Feb. 1

If possible, I would even like to be able to chain strings so that I can reference relative days from the new date:

如果可能的话,我甚至希望能够链接字符串,以便我可以引用新日期的相对日期:

# Should return 2 days before the Sunday before Feb. 1, 2012
date --d='Sunday before 02/1/2012 - 2 days'

Though this chaining is not as important. Is there some way for bash date to return a day based on the relative day of the week?

虽然这种链接并不重要。 bash日期是否有某种方式可以根据一周的相对日期返回一天?

3 个解决方案

#1


9  

You can use a little day number arithmetic:

你可以使用一个小数字算术:

base="02/1/2012"
feb1_dayofweek=$( date -d $base +%w )
target_dayofweek=0   # sunday
date -d "$base - $(( (7 + feb1_dayofweek - target_dayofweek) % 7 )) days"

result:

结果:

Sun Jan 29 00:00:00 EST 2012

#2


4  

Well with bash it can be done with some loop (e.g. get the date you want to use as a reference into a variable in Unix %s format than decrement it with 24*60*60 check if its Sunday, and print it if it's true...)

好吧,使用bash可以通过一些循环来完成(例如,将你希望用作Unix%s格式的变量的引用作为参考,而不是将其减去24 * 60 * 60,检查它是否为星期日,如果它是真的则打印出来...)

Or you can set up something like this with awk

或者你可以用awk设置这样的东西

 awk -v BASEDATE="2011 02 02" -v DIW="Sun" -v BEF="2"
       'BEGIN { ct=BASEDATE " 00 00 00"
                ct=mktime(ct)
                while (strftime("%a",ct) != DIW) { ct-=24*60*60 }
                ct-=BEF*24*60*60
                print strftime("%Y-%m-%d %a",ct)
              }'

You can see it in action here. Almost. As ideone (which I adore) does not allow passing command line variables to gawk (or I was lazy to figure it out ;-)), I had to embed them to the BEGIN block too.

你可以在这里看到它。几乎。由于ideone(我喜欢)不允许将命令行变量传递给gawk(或者我懒得想出来;-)),我不得不将它们嵌入到BEGIN块中。

If you want to you can convert the above to a datecalc.awk (with !#/usr/bin/gawk -f script which uses ARGV[n] variables instead of -v supplied ones so you can call it easily from your shell scripts.

如果你愿意,可以将上面的内容转换为datecalc.awk(使用!#/ usr / bin / gawk -f脚本,它使用ARGV [n]变量而不是-v提供的变量,这样你就可以从shell脚本中轻松调用它。

#3


2  

This is pretty easy to do if you have libfaketime installed.

如果你安装了libfaketime,这很容易做到。

export LD_PRELOAD=/usr/lib/libfaketime.so.1
$ FAKETIME='2012-02-01 00:00:00' date --d='last sunday'
Sun Jan 29 00:00:00 EST 2012

You can chain it by setting FAKETIME dynamically. This will get messy, but will work:

您可以通过动态设置FAKETIME来链接它。这会变得混乱,但会起作用:

$ FAKETIME=$(FAKETIME='2012-02-01 00:00:00' date --d="last sunday" '+%Y-%m-%d %H:%M:%S') date --d="-2 days"
Fri Jan 27 00:00:00 EST 2012

#1


9  

You can use a little day number arithmetic:

你可以使用一个小数字算术:

base="02/1/2012"
feb1_dayofweek=$( date -d $base +%w )
target_dayofweek=0   # sunday
date -d "$base - $(( (7 + feb1_dayofweek - target_dayofweek) % 7 )) days"

result:

结果:

Sun Jan 29 00:00:00 EST 2012

#2


4  

Well with bash it can be done with some loop (e.g. get the date you want to use as a reference into a variable in Unix %s format than decrement it with 24*60*60 check if its Sunday, and print it if it's true...)

好吧,使用bash可以通过一些循环来完成(例如,将你希望用作Unix%s格式的变量的引用作为参考,而不是将其减去24 * 60 * 60,检查它是否为星期日,如果它是真的则打印出来...)

Or you can set up something like this with awk

或者你可以用awk设置这样的东西

 awk -v BASEDATE="2011 02 02" -v DIW="Sun" -v BEF="2"
       'BEGIN { ct=BASEDATE " 00 00 00"
                ct=mktime(ct)
                while (strftime("%a",ct) != DIW) { ct-=24*60*60 }
                ct-=BEF*24*60*60
                print strftime("%Y-%m-%d %a",ct)
              }'

You can see it in action here. Almost. As ideone (which I adore) does not allow passing command line variables to gawk (or I was lazy to figure it out ;-)), I had to embed them to the BEGIN block too.

你可以在这里看到它。几乎。由于ideone(我喜欢)不允许将命令行变量传递给gawk(或者我懒得想出来;-)),我不得不将它们嵌入到BEGIN块中。

If you want to you can convert the above to a datecalc.awk (with !#/usr/bin/gawk -f script which uses ARGV[n] variables instead of -v supplied ones so you can call it easily from your shell scripts.

如果你愿意,可以将上面的内容转换为datecalc.awk(使用!#/ usr / bin / gawk -f脚本,它使用ARGV [n]变量而不是-v提供的变量,这样你就可以从shell脚本中轻松调用它。

#3


2  

This is pretty easy to do if you have libfaketime installed.

如果你安装了libfaketime,这很容易做到。

export LD_PRELOAD=/usr/lib/libfaketime.so.1
$ FAKETIME='2012-02-01 00:00:00' date --d='last sunday'
Sun Jan 29 00:00:00 EST 2012

You can chain it by setting FAKETIME dynamically. This will get messy, but will work:

您可以通过动态设置FAKETIME来链接它。这会变得混乱,但会起作用:

$ FAKETIME=$(FAKETIME='2012-02-01 00:00:00' date --d="last sunday" '+%Y-%m-%d %H:%M:%S') date --d="-2 days"
Fri Jan 27 00:00:00 EST 2012