Antworten:
Sie können den aktuellen Unix-Zeitstempel mit abrufen date "+%s"
, die aktuelle Viertelstunde mit ein paar einfachen Berechnungen ermitteln (mein Beispiel ist in bash
) und sie mit einem besseren Format ausdrucken mit date
:
curdate=`date "+%s"`
curquarter=$(($curdate - ($curdate % (15 * 60))))
date -d"@$curquarter"
Die @
Syntax zum Einstellen des aktuellen Datums und der Uhrzeit von einem Zeitstempel ist eine GNU-Erweiterung auf Datum. Wenn es auf Ihrem Betriebssystem nicht funktioniert, können Sie dasselbe tun (vergessen Sie nicht, UTC anzugeben, ansonsten hat es gewonnen). nicht funktionieren):
date -d"1970-01-01 $curquarter seconds UTC"
Die folgenden Methoden machen es unnötig, date
zweimal aufzurufen .
Der Overhead eines Systemaufrufs kann dazu führen, dass ein "einfacher" Befehl 100-mal langsamer ausgeführt wird als eine Bash-Operation in der eigenen lokalen Umgebung.
UPDATE Nur eine kurze Erwähnung zu meinem obigen Kommentar: "100 mal langsamer". Es kann jetzt " 500- mal langsamer" lauten ... Ich bin vor kurzem auf genau diese Frage gestoßen (nein, ich bin blindlings gegangen). Hier ist der Link: Schnelle Möglichkeit, eine Testdatei zu erstellen
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
oder
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
Beide Versionen werden nur zurückgegeben
2011.02.23 01:00
2011.02.23 01:15
2011.02.23 01:30
2011.02.23 01:45
Hier ist der erste mit einer TEST-Schleife für alle 60 Werte {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
oder sed
und auch das "unnötige" cat
vs <-Datei einen dramatischen Unterschied zur tatsächlichen Laufzeit macht. Beim Schleifen, wie in meinem Beispiel "500 mal langsamer". Es scheint also so, als ob date
ich die Shell wo immer möglich benutze und ein Programm wie das Batch-Verarbeiten zulasse. Gilles 'Left-Pad-0-Beispiel gegen printf
Hier ist eine Möglichkeit, Daten in der Shell zu bearbeiten. Rufen Sie zunächst date
auf, um die Komponenten abzurufen, und füllen Sie die Positionsparameter ( $1
, $2
usw.) mit den Komponenten (beachten Sie, dass dies einer der seltenen Fälle ist, in denen Sie $(…)
die Zeichenfolge außerhalb von Anführungszeichen in Wörter unterteilen möchten ). Führen Sie dann Arithmetik, Tests oder andere Aufgaben für die Komponenten durch. Zuletzt montieren Sie die Komponenten.
Der arithmetische Teil kann etwas knifflig sein, da Muscheln 0
als oktales Präfix behandelt werden. Zum Beispiel $(($5/15))
würde hier 8 oder 9 Minuten nach der vollen Stunde versagen. Da es höchstens einen führenden gibt 0
, ${5#0}
ist das arithmetisch sicher. Durch Hinzufügen von 100 und anschließendes Entfernen von 1
wird eine feste Anzahl von Stellen in der Ausgabe erhalten.
set $(date "+%Y %m %d %H %M")
m=$((100+15*(${5#0}/15)))
last_quarter_hour="$1.$2.$3 $4:${m#1}"
Vielleicht spielt es keine Rolle mehr, aber Sie könnten meine eigenen Datteln probieren . Mit dround
und einem negativen Argument wird auf Minuten gerundet:
dround now /-15m
=>
2012-07-11T13:00:00
Oder um Ihr Format einzuhalten:
dround now /-15m -f '%Y.%m.%d %H:%M'
=>
2012.07.11 13:00
dateutils.dround '2018-11-12 13:55' -15m
produziert 2018-11-12T13:15:00
nicht 2018-11-12T13:45:00
.
/-15m
dh auf das nächste Vielfache von 15 Minuten in der Stunde abrunden . Diese Funktion hat die umständlichere Syntax, weil sie weniger Werte akzeptiert. / -13m ist beispielsweise nicht möglich, weil 13 kein Teiler von 60 (Minuten in der Stunde) ist
Einige Shells können die Arbeit erledigen, ohne einen externen date
Befehl aufzurufen :
ksh
a=$(printf '%(%s)T\n'); printf '%(%Y.%m.%d %H:%M)T\n' "#$((a-a%(15*60)))"
bash a=$(printf '%(%s)T\n'); printf '%(%Y.%m.%d %H:%M)T\n' "$((a-a%(15*60)))"
zsh zmodload zsh/datetime; a=$EPOCHSECONDS; strftime '%Y-%m-%d %H:%M' $((a-a%(15*60)))
Die drei oben genannten Werte geben die Ortszeit (nicht UTC) an. Verwenden Sie bei Bedarf eine führende TZ = UTC0.
Die Syntax von ksh und bash ist nahezu identisch (mit Ausnahme der #
in ksh erforderlichen ). Für die zsh muss ein Modul geladen werden (im Lieferumfang der zsh-Distribution enthalten).
Es ist auch möglich, dies mit (GNU) awk zu tun:
gaffen awk 'BEGIN{t=systime();print strftime("%Y.%m.%d %H:%M",t-t%(15*60),1)}'
Dies liefert ein UTC-Ergebnis (ändern Sie das letzte 1
in 0
), wenn lokal benötigt wird. Das Laden eines externen awk- oder eines externen zsh-Moduls kann jedoch so langsam sein wie das Aufrufen von date selbst:
Gnu-Datum a=$(date +%s); date -ud "@$((a-a%(15*60)))" +'%Y.%m.%d %H:%M'
Eine kleine ausführbare Datei wie busybox
könnte ähnliche Ergebnisse liefern:
Busybox-Datum a=$(busybox date +%s);busybox date -ud "@$((a-a%(15*60)))" +'%Y.%m.%d %H:%M'
Beachten Sie, dass das führende Besetztbox-Wort möglicherweise weggelassen wird, wenn die Besetztbox mit diesen Namen in einem Verzeichnis des PFADS verknüpft ist.
Beide date
und busybox date
darüber werden UTC-Zeiten drucken. Entfernen Sie die -u
Option für Ortszeiten.
Wenn Ihr Betriebssystem eine eingeschränkte Version des Datums hat (und diese müssen Sie verwenden), versuchen Sie Folgendes:
a=$(date +%s); a=$(( a-a%(15*60) ))
date -d"1970-01-01 $a seconds UTC" +'%Y.%m.%d %H:%M'
Oder versuchen Sie in FreeBSD Folgendes:
a=$(date +%s); a=$(( a-a%(15*60) ))
date -r "$a" +'%Y.%m.%d %H:%M'
Wenn Sie zwei Mal mit dem Aufrufen des Datums leben können, funktioniert dies in bash unter Solaris:
date +"%Y.%m.%d %H:$(( $(date +'%M') / 15 * 15 ))"
Im Auftrag des Kommentars bearbeitet an:
date +"%Y.%m.%d %H:$(( $(date +'%M') / 15 * 15 ))" | sed 's/:0$/:00/'
Ich bin mir nicht sicher, was genau deine Anforderung ist. Wenn Sie jedoch die Zeit nach 15 Minuten generieren möchten, können Sie so etwas verwenden date -d '+15 min'
. Die Ausgabe wird unten gezeigt:
$ date; date -d '+15 min'
Tue Feb 22 18:12:39 IST 2011
Tue Feb 22 18:27:39 IST 2011