我正在尝试将描述时间间隔的字符串转换为相应的秒数。
经过一些实验,我发现我可以像这样使用 private void ChangeMessage(ref Message reply)
{
Message newMessage = null;
MessageBuffer msgbuf = reply.CreateBufferedCopy(int.MaxValue);
Message tmpMessage = msgbuf.CreateMessage();
XmlDictionaryReader xdr = tmpMessage.GetReaderAtBodyContents();
XElement bodyEl = XElement.Load(xdr.ReadSubtree());
var someElement= bodyEl.Descendants().FirstOrDefault(b => b.Name.LocalName == "somename");
XElement newElement = getNewSomeElement();//private method
someElement.ReplaceWith(newElement);//replacing node into body
MemoryStream ms = new MemoryStream();
XmlWriter xw = XmlWriter.Create(ms);
bodyEl.Save(xw);
xw.Flush();
xw.Close();
ms.Position = 0;
XmlReader xr = XmlReader.Create(ms);
//create new message from modified XML document
newMessage = Message.CreateMessage(reply.Version, null, xr);
newMessage.Headers.CopyHeadersFrom(reply);
newMessage.Properties.CopyProperties(reply.Properties);
reply = newMessage;
}
:
date
但我认为应该有一种更简单的方法将“5分10秒”之类的字符串转换为相应的秒数,在本例中为310. 有没有办法在一个命令中执行此操作?
注意:虽然可移植性很有用,但这不是我的首要任务。
答案 0 :(得分:7)
你可以从纪元开始
date -d"1970-01-01 00:00:00 UTC 5 minutes 10 seconds" "+%s"
310
你也可以很容易地分时
Time="1 day"
date -d"1970-01-01 00:00:00 UTC $Time" "+%s"
86400
答案 1 :(得分:1)
有一种方法可以在纯date
中使用bash
命令(为了便携性)
假设您只有一个输入字符串,可以在bash
变量中转换“5分10秒”并带有:
限制器,如下所示。
$ convertString="00:05:10"
$ IFS=: read -r hour minute second <<< "$convertString"
$ secondsValue=$(((hour * 60 + minute) * 60 + second))
$ printf "%s\n" "$secondsValue"
310
您可以直接在命令行上运行上述命令而不使用$
标记。
答案 2 :(得分:1)
这样做(添加纪元19700101):
$ date -ud '19700101 5 minutes 10 seconds' +%s
310
添加-u
以避免本地时间(和DST)效果非常重要。
$ TZ=America/Los_Angeles date -d '19700101 5 minutes 10 seconds' +%s
29110
请注意,日期可以做一些数学运算:
$ date -ud '19700101 +5 minutes 10 seconds -47 seconds -1 min' +%s
203
答案 3 :(得分:0)
修改:是的。我在评论后为OP开发了,并在Mac OS X,CentOS和Ubuntu上进行了检查。一个内衬,POSIX兼容命令,用于转换&#34; X分钟Y秒&#34;格式为秒。 那就是问题。
echo $(($(echo "5 minutes 10 seconds" | cut -c1-2)*60 + $(echo "5 minutes 10 seconds" | cut -c1-12 | awk '{print substr($0,11)}')))
OP通过评论告诉我,他想要&#34; X分钟Y秒&#34;格式不适用于HH:MM:SS
格式。 date
和"+%s"
的命令会在(我的)Mac上抛出错误。 OP希望从&#34; X分钟Y秒和#34;中获取数值。格式并将其转换为秒。首先,我用数字提取分钟(将其作为等式A):
echo "5 minutes 10 seconds" | cut -c1-2)
然后我提取了秒部分(将其作为等式B):
echo "5 minutes 10 seconds" | cut -c1-12 | awk '{print substr($0,11)}'
现在将分钟乘以60然后再加上另一个:
echo $((equation A)*60) + (equation B))
OP应该要求其他人检查我的开发版本(但正在工作)命令,然后再将其用于自动重复使用,就像在生产服务器上使用cron一样。
如果我们想在日志文件中运行此操作,其值为&#34; X分钟Y秒&#34;格式,我们必须将echo "5 minutes 10 seconds"
更改为cat file | ...
之类的命令。 I kept a gist of it too如果我或其他人需要,我们可以将其与cat
一起使用,以x minutes y seconds
日志格式运行服务器日志文件。
虽然偏离主题(我的理解,问题与当前时间没什么关系),但这对于POSIX兼容的操作系统无法在几秒钟内获得当前时间:
date -d "1970-01-01 00:00:00 UTC 5 minutes 10 seconds" "+%s"
它会在MacOS X上引发错误但在大多数GNU / Linux发行版上都有效。在复杂的使用情况下,+%s
部分将在符合POSIX的操作系统上抛出错误。这些命令主要适用于在POSIX上获得适用于任何类型的unix的操作时间,如OS:
awk 'BEGIN{srand(); print srand()}'
perl -le 'print time'
如果OP需要可以通过以秒为单位生成当前时间来延长它并减去。我希望它会有所帮助。
----旧编答案之前的答案----
您可以获得没有date
- echo | awk '{print systime();}'
或wget -qO- http://www.timeapi.org/utc/now?\\s
的当前时间。将时间转换为秒的其他方法是echo "00:20:40.25" | awk -F: '{ print ($1 * 3600) + ($2 * 60) + $3 }'
。
另一个答案中显示printf
的示例近乎完美。
GNU / Linux的基本实用程序 - gnu.org/../../../../../Setting-an-Alarm.html
总是需要你想要的东西接近方式取决于你需要多么万无一失的方式。
答案 4 :(得分:0)
先前的建议在alpine linux上无法正常工作,因此这里有一个符合POSIX的小助手功能,易于使用并且还支持计算(只是实现的副作用)。
该函数始终根据提供的参数返回整数。
$ durationToSeconds '<value>' '<fallback>'
$ durationToSeconds "1h 30m"
5400
$ durationToSeconds "$someemptyvar" 1h
3600
$ durationToSeconds "$someemptyvar" "1h 30m"
5400
# Calculations also work
$ durationToSeconds "1h * 3"
10800
$ durationToSeconds "1h - 1h"
0
# And also supports long forms for year, day, hour, minute, second
$ durationToSeconds "3 days 1 hour"
262800
# It's also case insensitive
$ durationToSeconds "3 Days"
259200
function durationToSeconds () {
set -f
normalize () { echo $1 | tr '[:upper:]' '[:lower:]' | tr -d "\"\\\'" | sed 's/ *y\(ear\)\{0,1\} */y /g; s/ *d\(ay\)\{0,1\} */d /g; s/ *h\(our\)\{0,1\} */h /g; s/ *m\(in\(ute\)\{0,1\}\)\{0,1\} */m /g; s/ *s\(ec\(ond\)\{0,1\}\)\{0,1\} */s /g; s/\([ydhms]\)s/\1/g'; }
local value=$(normalize "$1")
local fallback=$(normalize "$2")
echo $value | grep -v '^[-+*/0-9ydhms ]\{0,30\}$' > /dev/null 2>&1
if [ $? -eq 0 ]
then
>&2 echo Invalid duration pattern \"$value\"
else
if [ "$value" = "" ]; then
[ "$fallback" != "" ] && durationToSeconds "$fallback"
else
sedtmpl () { echo "s/\([0-9]\+\)$1/(0\1 * $2)/g;"; }
local template="$(sedtmpl '\( \|$\)' 1) $(sedtmpl y '365 * 86400') $(sedtmpl d 86400) $(sedtmpl h 3600) $(sedtmpl m 60) $(sedtmpl s 1) s/) *(/) + (/g;"
echo $value | sed "$template" | bc
fi
fi
set +f
}