Я никогда не видел, любой сказать "минус" за пределами математического сценария (для значения вычитают), "тире" является соответствующим и будет более распространенным, это не вещь Unix, это было просто этим человеком. У нас действительно есть другой малопонятный жаргон хотя, например. #!
объявлен хижиной.
Вот ссылка на текущий Файл Жаргона для ASCII и как они сказаны
Можно получить текущую метку времени 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"
Следующие методы делают ненужным звонить 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
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}"
Если можно жить с вызовом даты два раза, этих работ в ударе на Солярисе:
date +"%Y.%m.%d %H:$(( $(date +'%M') / 15 * 15 ))"
Отредактированный от имени комментария к:
date +"%Y.%m.%d %H:$(( $(date +'%M') / 15 * 15 ))" | sed 's/:0$/:00/'
Не уверено в Вашем строгом требовании. Однако, если Вы хотите генерировать время после 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
Возможно, это больше не имеет значения, но Вы могли попробовать мой очень собственный dateutils. Округление (вниз) к минутам, покончили dround
и отрицательный аргумент:
dround now /-15m
=>
2012-07-11T13:00:00
Или придерживаться Вашего формата:
dround now /-15m -f '%Y.%m.%d %H:%M'
=>
2012.07.11 13:00
Некоторые оболочки могут выполнять работу без вызова внешней 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
, может дать аналогичные результаты:
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'