дата: получите текущий 15-минутный интервал

Я никогда не видел, любой сказать "минус" за пределами математического сценария (для значения вычитают), "тире" является соответствующим и будет более распространенным, это не вещь Unix, это было просто этим человеком. У нас действительно есть другой малопонятный жаргон хотя, например. #! объявлен хижиной.

Вот ссылка на текущий Файл Жаргона для ASCII и как они сказаны

15
27.11.2015, 00:06
7 ответов

Можно получить текущую метку времени Unix с date "+%s", найдите текущую четверть часа с некоторой простой математикой (мой пример находится в bash) и распечатайте его назад с лучшим форматом с date :

curdate=`date "+%s"`
curquarter=$(($curdate - ($curdate % (15 * 60))))
date -d"@$curquarter"

@ синтаксис для назначения текущей даты и время от метки времени является расширением GNU до настоящего времени, если это не делает работ над ОС, можно сделать то же как это (не забывайте указывать UTC, иначе, это не будет работать):

date -d"1970-01-01 $curquarter seconds UTC"
17
27.01.2020, 19:49

Следующие методы делают ненужным звонить date дважды.
Издержки системного вызова могут сделать "простую" команду 100 временами медленнее, чем удар, делающий то же самое в его собственном окружении.

ОБНОВИТЕ Просто быстрое упоминание о моем выше комментария: "в 100 раз медленнее". Это может теперь читать "в 500 раз медленнее"... Я недавно упал (не, обойденный вслепую) в эту самую проблему. вот ссылка: Быстрый способ создать тестовый файл

eval $(date +Y=%Y\;m=%m\;d=%d\;H=%H\;M=%M)
[[ "$M" < "15" ]] && M=00 # cater for octal clash
M=$(((M/15)*15))
((M==0)) && M=00 # the math returns 0, so make it 00  
echo $Y.$m.$d $H:$M  

или

eval $(date +Y=%Y\;m=%m\;d=%d\;H=%H\;M=%M)
if   [[ "$M" < "15" ]] ; then M=00
elif [[ "$M" < "30" ]] ; then M=15
elif [[ "$M" < "45" ]] ; then M=30
else M=45
fi
echo $Y.$m.$d $H:$M

Обе версии возвратятся только

2011.02.23 01:00
2011.02.23 01:15
2011.02.23 01:30
2011.02.23 01:45   

Вот первый с Испытательным шлейфом для всех 60 значений {00.. 59}

for X in {00..59} ;                         ###### TEST
do                                          ###### TEST 
  eval $(date +Y=%Y\;m=%m\;d=%d\;H=%H\;M=%M)
  M=$X                                      ###### TEST 
  [[ "$M" < "15" ]] && M=00 # cater for octal clash
  M=$(((M/15)*15))
  ((M==0)) && M=00 # the math returns 0, so make it 00  
  echo $Y.$m.$d $H:$M 
done                                        ###### TEST 
5
27.01.2020, 19:49
  • 1
    Только для разъяснения — "системным вызовом", Вы имеете в виду "ветвление/должностное лицо/ожидание, как система () вызов", не системный вызов в целом. (Я упоминаю это, потому что создание системных вызовов также имеет издержки в рамках программы из-за переключателя пользователя/ядра. Это не конкретный вопрос здесь.) –  mattdm 06.03.2011, 08:03
  • 2
    mattdm... Спасибо.. Я работаю только с 6 месяцев опыт Linux, таким образом, я, довольно вероятно, использовал неправильную фразу, но я продолжаю читать об издержках, понесенных ненужными вызовами, и в моем собственном опыте тестирования моих собственных сценариев, я видел много примеров где вызов printf или sed и также настолько "ненужный" cat по сравнению с <файл действительно имеет поразительное фактическое значение во время выполнения. когда цикличное выполнение, как в моем "в 500 раз более медленном" примере.. Таким образом, кажется что с помощью оболочки по мере возможности и позволяя программу такой как date к пакетной обработке то, что я имею в виду.. например, пример Жабр Left-Pad-0, по сравнению с printf –  Peter.O 06.03.2011, 13:09

Вот способ работать над датами в оболочке. Сначала звоните date получить компоненты и заполнить позиционные параметры ($1, $2, и т.д.) с компонентами (отмечают, что это - один из этих редких случаев, где Вы действительно хотите использовать $(…) за пределами двойных кавычек, для повреждения строки в слова). Затем выполните арифметику, тесты, или независимо от того, что необходимо сделать на компонентах. Наконец соберите компоненты.

Арифметическая часть может быть немного хитрой, потому что оболочки рассматривают 0 как восьмеричный префикс; например, здесь $(($5/15)) перестал бы работать в 8 или 9 минут мимо часа. С тех пор существует самое большее одно продвижение 0, ${5#0} безопасно для арифметики. Добавление 100 и впоследствии разделение 1 путь состоит в том, чтобы получить постоянное число цифр в выводе.

set $(date "+%Y %m %d %H %M")
m=$((100+15*(${5#0}/15)))
last_quarter_hour="$1.$2.$3 $4:${m#1}"
3
27.01.2020, 19:49

Если можно жить с вызовом даты два раза, этих работ в ударе на Солярисе:

date +"%Y.%m.%d %H:$(( $(date +'%M') / 15 * 15 ))"

Отредактированный от имени комментария к:

date +"%Y.%m.%d %H:$(( $(date +'%M') / 15 * 15 ))" | sed 's/:0$/:00/'
1
27.01.2020, 19:49
  • 1
    В первом qurarter часа это произведет мелкий вывод только с единственным 0 вместо 00 –  Peter.O 22.02.2011, 16:40
  • 2
    , это - простой sed после исходной команды. –  ddeimeke 23.02.2011, 17:53
  • 3
    Еще одна ошибка: это не работает между H:08 и H:10. См. мой ответ для почему и фиксация. –  Gilles 'SO- stop being evil' 23.02.2011, 23:33

Не уверено в Вашем строгом требовании. Однако, если Вы хотите генерировать время после 15 минут, затем можно использовать что-то как date -d '+15 min'. Вывод показывают ниже:

$ date; date  -d '+15 min'
Tue Feb 22 18:12:39 IST 2011
Tue Feb 22 18:27:39 IST 2011
-1
27.01.2020, 19:49
  • 1
    Вы неправильно поняли вопрос. Точка является к раунду датой (вниз) к нескольким из 15 минут. –  Gilles 'SO- stop being evil' 22.02.2011, 21:45

Возможно, это больше не имеет значения, но Вы могли попробовать мой очень собственный dateutils. Округление (вниз) к минутам, покончили dround и отрицательный аргумент:

dround now /-15m
=>
  2012-07-11T13:00:00

Или придерживаться Вашего формата:

dround now /-15m -f '%Y.%m.%d %H:%M'
=>
  2012.07.11 13:00
2
27.01.2020, 19:49

Некоторые оболочки могут выполнять работу без вызова внешней dateкоманды:

a=$(printf '%(%s)T\n'); printf '%(%Y.%m.%d %H:%M)T\n' "#$((a-a%(15*60)))"
a=$(printf '%(%s)T\n'); printf '%(%Y.%m.%d %H:%M)T\n' "$((a-a%(15*60)))"
zmodload zsh/datetime; a=$EPOCHSECONDS; strftime '%Y-%m-%d %H:%M' $((a-a%(15*60)))

Три вышеперечисленных устройства обеспечивают местное (, а не UTC )время. При необходимости используйте начальный TZ=UTC0.

Синтаксис ksh и bash почти идентичен (, за исключением обязательного #в ksh ). Zsh требует загрузки модуля (, включенного в дистрибутив zsh ).

Это также можно сделать с помощью (GNU )awk:

awk 'BEGIN{t=systime();print strftime("%Y.%m.%d %H:%M",t-t%(15*60),1)}'

Это обеспечивает результат UTC (, изменяет последний 1на 0), если требуется локальный. Но загрузка внешнего модуля awk или внешнего модуля zsh может быть такой же медленной, как и вызов самой даты :

.

a=$(date +%s); date -ud "@$((a-a%(15*60)))" +'%Y.%m.%d %H:%M'

Небольшой исполняемый файл, такой как busybox, может дать аналогичные результаты:

a=$(busybox date +%s);busybox date -ud "@$((a-a%(15*60)))" +'%Y.%m.%d %H:%M'

Обратите внимание, что начальное слово busybox может быть опущено, если busybox связан с этими именами в каталоге PATH.

И date, и busybox dateвыше будут печатать время UTC. Удалите опцию -uдля местного времени.


Если ваша ОС имеет более ограниченную версию даты (и именно ее вы должны использовать ), попробуйте:

a=$(date +%s); a=$(( a-a%(15*60) ))
date -d"1970-01-01 $a seconds UTC" +'%Y.%m.%d %H:%M'

Или, если вы используете FreeBSD, попробуйте:

a=$(date +%s); a=$(( a-a%(15*60) ))
date -r "$a" +'%Y.%m.%d %H:%M'
2
27.01.2020, 19:49

Теги

Похожие вопросы