2016-05-26 3 views
1

Я пытаюсь преобразовать временные метки, считанные из файла, начиная со строки до даты, так что я могу найти разницу в 2 датах/временных меток. большинство потоков/обсуждений на веб-шоу используют аргумент даты «-d», чтобы преобразовать строку в эпоху или найти разницу в двух временных отметках Find difference between two dates in bashДата: незаконный вариант - d, Найти разницу между двумя датами

Но похоже, что моя среда/ОС не поддерживает -d аргумент даты. Ниже приведены подробные сведения о моем окр: даты

bash --version 
GNU bash, version 3.2.52(1)-release (i386-pc-solaris2.10) 
Copyright (C) 2007 Free Software Foundation, Inc. 

uname -a 
SunOS s01***** 5.10 Generic_147148-26 i86pc i386 i86pc 

Примера чтение из файла:

START_TIME="09/03/16 - 01:04:56" 
END_TIME="09/03/16 - 05:10:44" 

кода, который я пытался я пытался имитировать ниже код из Find difference between two dates in bash

!# /usr/bin/sh 

date1="Sat Dec 28 03:22:19 2013" 
date2="Sun Dec 29 02:22:19 2013" 
date -d @$(($(date -d "$date2" +%s) - $(date -d "$date1" +%s))) -u +'%H:%M:%S' 

bash test.sh 
date: illegal option -- d 
usage: date [-u] mmddHHMM[[cc]yy][.SS] 
     date [-u] [+format] 
     date -a [-]sss[.fff] 
date: illegal option -- d 
usage: date [-u] mmddHHMM[[cc]yy][.SS] 
     date [-u] [+format] 
     date -a [-]sss[.fff] 
test.sh: line 5: - : syntax error: operand expected (error token is " ") 

Я не думаю, что синтаксическая ошибка в строке 5 является основной причиной, по которой я не нашел вариант -d в man-странице моей даты.

В ответ на замечания:

>>> date --version 
    date: illegal option -- version 
    usage: date [-u] mmddHHMM[[cc]yy][.SS] 
      date [-u] [+format] 
      date -a [-]sss[.fff] 
    >>> date --help 
    date: illegal option -- help 
    usage: date [-u] mmddHHMM[[cc]yy][.SS] 
      date [-u] [+format] 
      date -a [-]sss[.fff] 
    >>> echo $0 
    bash 

Даже эти аргументы не поддерживаются. Извиняюсь, если я совершу любую глупую ошибку.

Возможно, кто-то, пожалуйста, дайте мне эквивалент -d для общих сведений env, приведенных выше, или способ найти разницу между двумя датами без использования -d.

Заранее спасибо

+2

IMHO, лучший пост 'date -version' и' date -help' ('date -help | fgrep -d' для более короткого вывода) вместо' bash -version'. Или, в дополнение к 'bash --version'. – Sasha

+0

Можете ли вы опубликовать фактическую ошибку, а также, пожалуйста. – 123

+1

Uer Perl. Смотрите: http://stackoverflow.com/a/95539/3776858 – Cyrus

ответ

0

В соответствии со стандартом POSIX, date не делает дату и время математику для вас. Он получает или задает дату и время системы, возможно, с настройками часового пояса. См. date(1) и обратите внимание на отсутствие опции -d (или, действительно, любые интересные варианты!).

Вопрос становится «Как сделать математику даты и времени без date?» Временные метки, которые вы указали, не имеют информации о часовом поясе, поэтому обычное поведение должно предполагать местное время. Местное время: bad. Шутки в сторону. Некоторые часовые пояса имеют crazy discontinuities или не имели значимого существования сотни лет назад (например, большинство американских часовых поясов). Поэтому, хотя вы могли бы взломать собственное решение, которое работает в вашей конкретной части мира в недавнем прошлом, оно просто не будет надежным.

Если вы можете получить свои временные метки во время Unix, вы можете просто их вычесть, и это даст вам правильный ответ mostly but not entirely. К сожалению, насколько мне известно, это невозможно сделать в командной строке. Unix предоставляет strptime(3), чтобы сделать это с C (и оттуда вы переходите к mktime(3), как показано в this answer), но я не верю, что есть полностью стандартная утилита, которая предоставляет для этого интерфейс командной строки. Возможно, вам придется писать и компилировать свои собственные.

Корректировка для прыжковых секунд сложна в крайнем случае, поскольку, насколько мне известно, POSIX никогда не предоставлял стандартный интерфейс для определения того, когда в прошлые времена произошли прыжки. Такой интерфейс потребует подключения к Интернету, чтобы оставаться актуальным, что, вероятно, является не стартером для ряда реализаций.Не зная больше о вашей системе и ее возможностях, я просто не могу придумать, что будет или не будет работать для вашего случая использования.

1

awkmktime имеет неплохие шансы существующих в вашей системе:

#!/bin/bash 

START_TIME="09/03/16 - 01:04:56" 
END_TIME="09/03/16 - 05:10:44" 

echo -e "$START_TIME\n$END_TIME" | 
    tr '/:-' ' ' | 
    awk '{print "20"$3" "$2" "$1" "$4" "$5" "$6}' | 
    awk '{printf "%s ", mktime($0)}' | 
    awk '{print $2 - $1}' 

объяснение:

  1. echo как раз строки
  2. tr преобразует 09/03/16 - 01:04:56 в 09 03 16 01:04:56
  3. первый awk с hanges 09 03 16 01 04 56 к 2016 03 09 01 04 56
  4. второй awk преобразует 2016 03 09 01 04 56 к эпохе времени: 1457514296 и печатает как на одной строке: 1457514296 1457529044
  5. третий awk вычитает первое из второго, что дает разницу в секундах: 14748

в awk сек может также легко объединяются, но здесь я сохранял каждый отдельный для ясности.

+0

mktime [нестандартно] (http://pubs.opengroup.org/onlinepubs/9699919799/utilities/awk.html#tag_20_06_13_14) и может не существовать под 'awk' OP. – Kevin

+0

Привет, Уэбб, спасибо за пошаговое руководство, я понял, что вы предложили, но когда я попытался подражать одному и тому же коду, результат раздражает. Для любых значений времени начала и окончания я получаю тот же результат «2013». Даже когда обе метки времени одинаковы. Тогда я понял, что третий awk делает «2016-03 = 2013» вместо «end_time - start_time». Я думаю, как сказал Кевин, mktime не поддерживается моей env. Любые предложения по преодолению этого? Благодарю. – whirlcano

+0

сначала попробуйте 'gawk' вместо' awk' в случае, который существует в вашей системе. в противном случае существует субоптимальное решение, которое заключается в том, чтобы получить секунды, умножив минутное поле на 60, час на 60 * 60, день на 60 * 60 * 24, месяц на ... ну, если 'if' который умножает каждый месяц на количество секунд в этом месяце ... а затем поле года на 365,25 * 24 * 60 * 60. – webb