Datum: Aktuelles 15-Minuten-Intervall abrufen


15

Kann ich das aktuelle 15-Minuten-Intervall mit dem Befehl date oder einem ähnlichen Befehl abrufen?

ZB %Y.%m.%d %H:%M wird mir so etwas wie Datum geben 2011.02.22 10:19, ich brauche etwas, das 2011.02.22 10:15in der Zeitspanne von 10:15bis nach nachgibt 10:29.

Antworten:


17

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"

5

Die folgenden Methoden machen es unnötig, datezweimal 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 

1
Nur zur Verdeutlichung - mit "Systemaufruf" meinen Sie "fork / exec / wait, wie der system () -Aufruf", nicht den Systemaufruf im Allgemeinen. (Ich erwähne dies, weil das
Tätigen von Systemaufrufen

mattdm ... Danke .. Ich arbeite seit nur 6 Monaten mit Linux, daher habe ich höchstwahrscheinlich den falschen Ausdruck verwendet, aber ich lese immer wieder über die Unkosten, die durch unnötige Aufrufe entstehen, und über meine eigenen Erfahrungen beim Testen meiner eigenen Skripte, ich habe viele Beispiele gesehen, bei denen das Aufrufen von printfoder sedund auch das "unnötige" catvs <-Datei einen dramatischen Unterschied zur tatsächlichen Laufzeit macht. Beim Schleifen, wie in meinem Beispiel "500 mal langsamer". Es scheint also so, als ob dateich die Shell wo immer möglich benutze und ein Programm wie das Batch-Verarbeiten zulasse. Gilles 'Left-Pad-0-Beispiel gegen printf
Peter.O

3

Hier ist eine Möglichkeit, Daten in der Shell zu bearbeiten. Rufen Sie zunächst dateauf, um die Komponenten abzurufen, und füllen Sie die Positionsparameter ( $1, $2usw.) 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 0als 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 1wird 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}"

"Die Tricks des Handels" ... eine gute. :)
Peter.O

2

Vielleicht spielt es keine Rolle mehr, aber Sie könnten meine eigenen Datteln probieren . Mit droundund 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

funktionieren deine utils dann überhaupt noch so? mit -15m bekomme ich den eingang auf die nächsten 15 minuten nach einer stunde zurückgespult: dateutils.dround '2018-11-12 13:55' -15mproduziert 2018-11-12T13:15:00nicht 2018-11-12T13:45:00.

1
@JackDouglas Die Tools haben sich weiterentwickelt, was Sie jetzt wollen: /-15mdh 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
hroptatyr

schön, ich bekomme was ich jetzt brauche dateutils.dround '2018-11-12 12:52:31' /450s /-15m, danke!

2

Einige Shells können die Arbeit erledigen, ohne einen externen dateBefehl aufzurufen :

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)))

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:

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 1in 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:

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

Eine kleine ausführbare Datei wie busyboxkönnte ähnliche Ergebnisse liefern:

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 dateund busybox datedarüber werden UTC-Zeiten drucken. Entfernen Sie die -uOption 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'

1

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/'

1
Im ersten Quartal der Stunde wird dies eine Minutenausgabe mit nur einer einzelnen 0 anstelle von 00
erzeugen

Korrigiert ist es ein einfaches Sed nach dem ursprünglichen Befehl.
Ddeimeke

Ein weiterer Fehler: Es funktioniert nicht zwischen H: 08 und H: 10. Siehe meine Antwort für das Warum und eine Lösung.
Gilles 'SO- hör auf böse zu sein'

-1

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

1
Sie haben die Frage falsch verstanden. Es geht darum, das Datum auf ein Vielfaches von 15 Minuten abzurunden.
Gilles 'SO- hör auf böse zu sein'
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.