Как вычесть миллисекунды из времени в этом формате: «2020-01-06 11: 27: 12.280» в сценарии оболочки - PullRequest
0 голосов
/ 06 января 2020

У меня есть формат времени 2020-01-06 11:27:12.280, где .280 - это миллисекунды. Я хочу вычесть 500 миллисекунды из этого времени и снова получить результат в том же формате времени.

Я попытался преобразовать время в дату эпохи с помощью этой команды:

date +%s -d"2020-01-06 11:27:12.280

, но не считает миллисекунды.

1 Ответ

3 голосов
/ 06 января 2020

GNU: Используя GNU date , можно выполнять вычитание непосредственно в команде date. Это продемонстрировано в комментарии Léa Gris :

$ date -d "2020-01-06 11:27:12.280 - 0.5 sec" '+%F %T.%3N'
2020-01-06 11:27:11.780

Это работает здесь, потому что GNU date имеет возможность запрашивать любую строку даты с использованием флага -d и знает о наносекунд.

BSD / MacOS: Дата BSD ведет себя по-разному. Вам нужно немного больше работы здесь:

$ d="2020-01-06 11:27:12.280"
$ d=$(( $(date -j -f "%F %T" "${d%.*}" "+%s")${d#*.} - 500 ))
$ date -r "${d%${d: -3}}" "+%F %T.${d: -3}"
2020-01-06 11:27:11.780

POSIX: Если вы хотите быть совместимым с POSIX, это другая история. В соответствии со стандартом POSIX команда date не может использоваться здесь, поскольку вы не можете установить свою собственную дату-время с флагом -d, а также нет формата, который задает мили или наносекунды. Следовательно, нужно использовать разные инструменты. Есть много возможных способов, но мы будем использовать здесь версию POSIX awk:

awk -v d='2020-01-06 11:27:12.280' '
BEGIN{ gsub(/[-:]/," ",d); strftime_posix(mktime_posix(d)-0.5) }

# Algorithm from "Astronomical Algorithms" By J.Meeus
function mktime_posix(datestring,    a,t) {
    split(datestring,a," ")
    if (a[1] < 1970) return -1
    if (a[2] <= 2) { a[1]--; a[2]+=12 }
    t=int(a[1]/100); t=2-t+int(t/4)
    t=int(365.25*a[1]) + int(30.6001*(a[2]+1)) + a[3] + t - 719593
    return t*86400 + a[4]*3600 + a[5]*60 + a[6]
}

function strftime_posix(epoch, JD,yyyy,mm,dd,HH,MM,SS,A,B,C,D,E ) {
    if (epoch < 0 ) return "0000 00 00 00 00 00.000000"
    JD=epoch; SS=JD%60; JD-=SS; JD/=60; MM=JD%60;
    JD-=MM; JD/=60; HH=JD%24; JD-=HH; JD/=24;
    JD+=2440588
    A=int((JD - 1867216.25)/(36524.25))
    A=JD+1+A-int(A/4)
    B=A+1524; C=int((B-122.1)/365.25); D=int(365.25*C); E=int((B-D)/30.6001)
    dd=B-D-int(30.6001*E)
    mm = E < 14 ? E-1 : E - 13
    yyyy=mm>2?C-4716:C-4715
    return sprintf("%0.4d-%0.2d-%0.2d %0.2d:%0.2d:%06.3f",yyyy,mm,dd,HH,MM,SS)
}
'
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...