如何为存储在变量中的日期/时间添加间隔 [英] How to add an interval to a date/time stored in a variable

查看:43
本文介绍了如何为存储在变量中的日期/时间添加间隔的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在Fedora 27机器上编写bash脚本.该脚本每隔一段时间运行一个Python程序,偶尔显示进度消息.除了在存储在变量中的时间间隔上添加一行的行之外,该行均有效.

I'm writing a bash script on a Fedora 27 machine. This script runs a Python program at intervals, displaying occasional progress messages. It's working except for a line that adds an interval to a time stored in a variable.

有人知道如何做到这一点吗?

Does anyone know how to accomplish this?

这是脚本的最低版本.

#!/usr/bin/env bash

next_run_dat=${1}
echo -n 'Next run will be at: ';echo ${next_run_dat}

now_dat=`date +'%Y-%m-%d %H:%M:%S'`
echo -n 'The time is now: ';echo ${now_dat}

while [[ ${now_dat} < ${next_run_dat} ]]
do
    sleep 10
    now_dat=`date +'%Y-%m-%d %H:%M:%S'`
    echo -n 'The time is now: ';echo ${now_dat}
done

while true
do
    echo 'This line represents a run.'
    sleep 5

    # ==> PROBLEM LINE BELOW <==
    next_run_dat=$(date -d "${next_run_dat} + 25 seconds" +'Y-%m-%d %H:%M:%S')
    echo -n 'Next run will be at: ';echo ${next_run_dat}

    now_dat=`date +'%Y-%m-%d %H:%M:%S'`
    echo -n 'The time is now: ';echo ${now_dat}

    while [[ ${now_dat} < ${next_run_dat} ]]
    do
        sleep 5
        now_dat=`date +'%Y-%m-%d %H:%M:%S'`
        echo -n 'The time is now: ';echo ${now_dat}
    done
done

这是运行最低版本的输出:

And here's the output from running the minimal version:

$ bash control_bash_minimal.sh '2018-07-23 09:38:00'
Next run will be at: 2018-07-23 09:38:00
The time is now: 2018-07-23 09:37:36
The time is now: 2018-07-23 09:37:46
The time is now: 2018-07-23 09:37:56
The time is now: 2018-07-23 09:38:06
This line represents a run.
date: invalid date ‘2018-07-23 09:38:00 + 25 seconds’
Next run will be at: 
The time is now: 2018-07-23 09:38:11
This line represents a run.
Next run will be at: Y-07-23 09:38:41
The time is now: 2018-07-23 09:38:16
^C

非常感谢您对此问题的任何帮助.

Thanks very much in advance for any help with this problem.

推荐答案

注意:这是对摘录自

组合的日期和时间项ISO 8601日期和时间扩展格式由ISO 8601日期,"T"字符分隔符和ISO 8601时间组成.如果将"T"替换为空格,则也可以识别这种格式.

Combined date and time of day items The ISO 8601 date and time of day extended format consists of an ISO 8601 date, a ‘T’ character separator, and an ISO 8601 time of day. This format is also recognized if the ‘T’ is replaced by a space.

在这种格式下,一天中的时间应使用24小时表示法.允许小数秒,小数点前可以带逗号或句点.不支持ISO 8601的小数分钟和小时.通常,主机支持纳秒级的时间戳分辨率;多余的精度会被静默丢弃.

In this format, the time of day should use 24-hour notation. Fractional seconds are allowed, with either comma or period preceding the fraction. ISO 8601 fractional minutes and hours are not supported. Typically, hosts support nanosecond timestamp resolution; excess precision is silently discarded.

可悲的是,他们没有提及是否应包括时区.

Sadly enough they make no mention of whether or not a time-zone should be included.

试图解开源代码和使用过的 GNUlib 给我的感觉是 chepner 是正确的.符号的双重用法使日期解析器停滞不前.为了更正确,它假定 + -之后的第一个数字是时区偏移量,以小时为单位.通常,时区的格式为 + HH:MM -HH:MM ,但单个数字会将其实现为 + HH:00 .显然,该数字必须小于或等于24.例如:

Trying to disentangle the source code and the used GNUlib gives me the feeling that chepner is correct. The double usage of the sign brakes the date parser. To be more correct, it assumes that the first number after + or - is a time-zone offset in hours. Normally, time zones have the format +HH:MM or -HH:MM, but a single number implements it as +HH:00. Evidently, the number has to be smaller than or equal to 24. Example:

$ TZ=UTC date -d "2018-07-23T09:38:00 + 9 seconds"
Mon 23 Jul 00:38:01 UTC 2018
$ TZ=UTC date -d "2018-07-23T09:38:00 + 9 2 seconds"
Mon 23 Jul 00:38:02 UTC 2018

此处,假定日期为UTC + 09:00,并将其转换为UTC,并以一秒为单位递增,在第二种情况下为2秒.

Here, the date is assumed to be in UTC+09:00 and converted to UTC and incremented with a single second and in the second case two seconds.

OP的示例失败,因为假定 + 25秒为UTC + 25:00,但这是一个无效的时区:

The example of the OP fails because + 25 seconds is assumed to be UTC+25:00, but this is an invalid time zone:

$ date -d "2018-07-23T09:38:00 + 25 seconds"
date: invalid date ‘2018-07-23T09:38:00 + 25 seconds’

那么,如何在不陷入TZ陷阱的情况下增加相对时间?

日期解析器期望相对时间使用带符号或无符号的数字.因此,我们实际上并不需要添加加号,因此我们可以通过删除 + 符号来利用这一点来增加时间:

The date parser expects a signed or unsigned number for relative times. Hence we don't really need to add the plus sign and thus we can exploit this for adding time by removing the + sign:

$ date -d "2018-07-23T09:38:00 25 seconds"
Mon 23 Jul 09:38:25 UTC 2018

这仅在您添加相对时间时有效,而在您减去时间时无效.但是同样,我们可以通过在解析器中添加前零秒,几小时或几天或任何零天来欺骗解析器:

This however only works when you add relative time and not when you subtract it. But again, we can trick the parser by adding first ZERO seconds or hours or days or whatever to it:

$ date -d "2018-07-23T09:38:00 - 25 seconds"
date: invalid date ‘2018-07-23T09:38:00 - 25 seconds’
$ date -d "2018-07-23T09:38:00 0 hours - 25 seconds"
Mon 23 Jul 09:37:35 UTC 2018

您还可以使用关键字 next prev :

You can also make use of the keywords next and prev:

$ date -d "2018-07-23T09:38:00 next 25 seconds"
Mon 23 Jul 09:38:25 UTC 2018
$ date -d "2018-07-23T09:38:00 prev 25 seconds"
Mon 23 Jul 09:37:35 UTC 2018

如果时区不是很重要,只需在UTC中运行,只需在字符串末尾添加 Z .

If the time zone if not really of importance, simply work in UTC, just add a Z to the end of the string.

$ date -d "2018-07-23T09:38:00Z + 25 seconds"
Mon 23 Jul 09:38:25 UTC 2018

但是最简单的方法是使用浮点数.由于时区的时区为HH:MM,浮点数不能解释为时区,因此

But the easiest of all is to use float-numbers. As time-zones timezones are given as HH:MM a float cannot be interpreted as a time-zone and thus

$ date -d "2018-07-23T09:38:00 + 25.0 seconds"
Mon 23 Jul 09:38:25 UTC 2018
$ date -d "2018-07-23T09:38:00 - 25.0 seconds"
Mon 23 Jul 09:37:35 UTC 2018

这篇关于如何为存储在变量中的日期/时间添加间隔的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆