如何让 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
How do I get the bash date script to return a day of the week relative to a non-current time?
提问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
