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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/9203747/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-18 01:31:00  来源:igfitidea点击:

How do I get the bash date script to return a day of the week relative to a non-current time?

linuxbashdate

提问by Roman

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

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

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 date 有没有办法根据一周中的相对日期返回一天?

回答by glenn Hymanman

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

回答by Zsolt Botykai

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 BEGINblock too.

你可以在这里看到它的实际效果。几乎。由于ideone(我很喜欢)不允许将命令行变量传递给gawk(或者我懒得弄清楚;-)),我也不得不将它们嵌入到BEGIN块中。

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

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

回答by frankc

This is pretty easy to do if you have libfaketimeinstalled.

如果您安装了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