Comparaison heure

Bonsoir,

Je cherche à comparer l’heure actuelle en fonction d’une heure max.

exemple : 23:10:34 est plus petit que 00:00:01

J’essaye un truc du genre mais qui ne marche pas :

#!/bin/bash
a=$(date +"%T")
b="00:00:01"

if [ "$a" -lt "$b" ]; then
        echo "avant"
else
        echo "apres"
fi

Quel est le moyen pour comparer les heures ?

Merci

Séparer heure-minute-seconde, puis dans l’ordre comparer les heures, si égales les minutes, si égales les secondes, et tu as ta réponse.
Tu peux séparer avec cut -d ‘:’ (si tu fais du shell)

Tu vas avoir un problème d’incohérence, car, avec des notations abusives, on peut avoir 00:00:02 < 23:59:00 < 00:00:01.
Je ne sais pas exactement dans quel contexte tu as besoin de cette comparaison, mais choisir 23:59:59 comme heure max semblerait plus approprié.

En convertissant tout en nombre de secondes depuis époque :

[code]#!/bin/bash
a=$(date +"%s")
b=“00:00:01"
limit=$(date “-d$b” +”%s")

if [ “$a” -lt “$limit” ]; then
echo "avant"
else
echo "apres"
fi[/code]

Par définition 00:00:00 est le début de la journée, donc la plus petite heure possible.
Si tu veux que 23:10:34 soit plus petit que 00:00:01 il te faut un troisième point de référence, un nouveau “début de journée”.
DEBUT <= 23:10:34 <= 00:00:01 < DEBUT

En d’autres termes, c’est bien gentil de dire que 23:10:34 est plus petit que 00:00:01, mais qu’est-ce qui est plus grand que 00:00:01 ? Certainement 00:00:02, mais quid de 04:00:00 c’est plus grand ou plus petit que 00:00:01 ? Et 12:00:00 ? Etc.
L’énoncé de ton problème est incomplet.

Bonjour,

En fait je lance un script qui me sauvegarde mes documents.

Si le script est lancé à 23:10:34 le 16/07/2012 la sauvegarde porte le nom du jour en cours, en revanche si je lance la sauvegarde après 00:00:00 elle portera le nom du jour suivant 17/07/2012 :075

Donc ma démarche est de nommer la sauvegarde de la journée travaillée, je ne sais pas si je suis clair…

Si sauvegarde lancée avant heure max 00:00:00 alors nom sauvegarde = date du jour
Si sauvegarde lancée après heure max 00:00:00 alors nom sauvegarde = date du jour -1

Heure max peut être aussi 23:59:59 comme le fait remarquer arnaud_k

[quote=“seb”]Si le script est lancé à 23:10:34 le 16/07/2012 la sauvegarde porte le nom du jour en cours, en revanche si je lance la sauvegarde après 00:00:00 elle portera le nom du jour suivant 17/07/2012 :075

Donc ma démarche est de nommer la sauvegarde de la journée travaillée, je ne sais pas si je suis clair…

Si sauvegarde lancée avant heure max 00:00:00 alors nom sauvegarde = date du jour
Si sauvegarde lancée après heure max 00:00:00 alors nom sauvegarde = date du jour -1[/quote]
Donc je répète : il te faut choisir arbitrairement une heure de référence spécifique qui sera la limite à partir de laquelle on passe de hier à aujourd’hui, étant donné que minuit ne te convient pas pour cette tâche.
En fait ton code d’origine est bon (edit: presque, il faut utiliser < au lieu de -lt), mais ton raisonnement en “langage naturel” est erroné et te fait choisir un mauvais point de référence (00:00:01 ne te laisse qu’une seule seconde – minuit pile – où tu considères que tu es encore “hier”). Une heure trop proche de minuit ne convient pas, bien au contraire il faut s’en éloigner le plus possible.

Essaye par exemple en prenant comme référence 04:00:00 tu verras que ça marche beaucoup mieux :

si heure < 04:00:00 (heure est toujours >= 00:00:00, pas besoin de faire le test) date d'hier sinon (du coup 04:00:00 <= heure <= 23:59:59) date d'aujourd'hui
En d’autres termes :

[quote]Si sauvegarde lancée avant heure max 04:00:00 alors nom sauvegarde = date du jour -1
Si sauvegarde lancée après heure max 04:00:00 alors nom sauvegarde = date du jour[/quote]

Non car dans ce cas là, si tu fais une sauvegarde à 23:50:00 ça prendra la date de la veille et non celle du jour (et je doute que ça soit ce que tu veux).
Il faut choisir soigneusement ton point de référence, la question que tu dois te poser est “jusqu’à quelle heure est-ce que je considère qu’on est encore hier ?”.

Tu as parfaitement raison, syam, mais il n’y a pas de code pour comparer les heures. Ma solution compare des date et thuban a décris une solution. J’en présente une autre un peu plus légère.

#!/bin/bash
a=$(date +"%T")
b="04:00:00"

if [ "${a//:/}" -lt "${b//:/}" ]; then
        echo "jour -1"
else
        echo "jour courant"
fi

Oups oui -lt compare des entiers et non pas des chaînes, j’avais zappé (quelle idée aussi de faire l’inverse de perl :stuck_out_tongue:).
Mais à partir du moment où les heures sont dans un format fixe (24h et un nombre de digits fixes, date +%T remplit parfaitement ce rôle) la comparaison des chaînes fonctionne très bien, pas besoin de s’embêter à découper la chaîne. Le code ci-dessous marche aussi bien avec bash que dash (sh) :

if [ "02:00:00" \< "04:00:00" ]; then echo "vrai" fi if [ "06:00:00" \< "04:00:00" ]; then echo "faux" fi if [ "02:00:00" \> "04:00:00" ]; then echo "faux" fi if [ "06:00:00" \> "04:00:00" ]; then echo "vrai" fi
Idem avec les dates du moment que c’est un format YYYY-MM-DD HH:NN:SS (chiffres les plus significatifs au début de la chaîne).

Tu as encore une fois raison. Je n’avais même pas imaginé cette possibilité. Ça marche en bash (et en bourne shell il semble) mais pas en zsh (c’est la première fois que je vois une syntaxe qui marche en bourn shell qui ne marche pas en zsh :017 ).

C’est un truc que je fais assez souvent pour éviter de parser les dates/heures. Quoi, fainéant moi ? :eusa-whistle:
Ok, ça implique que le jeu de caractères soit correctement ordonné pour les chiffres 0…9 mais bon même un truc tordu comme l’EBCDIC répond à ce critère, aucune raison de s’en inquiéter donc. :wink:
Et bien entendu comme je le précisais dans mon message précédent, il faut que la date/heure ait ses digits les plus significatifs en début de chaîne, quel que soit le format exact (mais perso je bosse quasi en permanence avec des dates ISO ça simplifie beaucoup les choses).

En bash on pourrait aussi écrire le test [[ “02:00:00” < “04:00:00” ]] mais du coup ça ne marcherait plus avec dash/sh. Par contre je pense que ça marcherait avec zsh, d’après la doc.
À mon avis dans la version que j’avais donnée c’est juste un problème d’échappement des caractères < et >, ceci devrait marcher pour zsh (et bash/dash le gèrent correctement) : [ “02:00:00” ‘<’ “04:00:00” ]

Je vais peut-être intervenir comme un cheveu sur la soupe, mais comme visiblement l’heure de référence est arbitraire, autant comparer l’heure courante avec 24h00m00s, ou plus simple selon le mode de comparaison avec 23h59m60s. C’est une autre façon d’écrire minuit en étant sûr d’être après n’importe quelle heure de la journée :think:

Le problème c’est justement que c’est comparer avec minuit qui est l’erreur de logique.
Il n’y a jamais besoin de comparer avec minuit :

  • soit minuit est écrit 00:00:00 et n’importe quelle heure sera obligatoirement supérieure à minuit
  • soit minuit est écrit 24:00:00 et n’importe quelle heure sera obligatoirement inférieure à minuit

Le but est justement de partitionner la journée en deux pour que des heures appartenant à aujourd’hui (dans l’intervalle minuit -> point de référence) puissent être considérées comme appartenant à hier, et ça ne peut se faire qu’en prenant un point de référence arbitraire différent de minuit (ce point de référence étant le moment où on considère qu’on passe d’hier à aujourd’hui).

C’est un truc que je fais assez souvent pour éviter de parser les dates/heures. Quoi, fainéant moi ? :eusa-whistle:
Ok, ça implique que le jeu de caractères soit correctement ordonné pour les chiffres 0…9 mais bon même un truc tordu comme l’EBCDIC répond à ce critère, aucune raison de s’en inquiéter donc. :wink:
Et bien entendu comme je le précisais dans mon message précédent, il faut que la date/heure ait ses digits les plus significatifs en début de chaîne, quel que soit le format exact (mais perso je bosse quasi en permanence avec des dates ISO ça simplifie beaucoup les choses).[/quote]
Je ne fais pas assez de scripting sheel pour avoir beaucoup rencontré ce problème (en fait j’en fait principalement pour répondre au forum).

En bash on pourrait aussi écrire le test [[ “02:00:00” < “04:00:00” ]] mais du coup ça ne marcherait plus avec dash/sh. Par contre je pense que ça marcherait avec zsh, d’après la doc.
À mon avis dans la version que j’avais donnée c’est juste un problème d’échappement des caractères < et >, ceci devrait marcher pour zsh (et bash/dash le gèrent correctement) : [ “02:00:00” ‘<’ “04:00:00” ][/quote]
Oui la solution [[ "02:00:00" < "04:00:00" ]](c’est ce qui est décrit dans le man), mais avec des crochets simples non (quelque soit la manière de l’échapper. Ce qui me surprend c’est que jusqu’à maintenant je pensais qu’un script shell POSIX passait tel quel avec zsh. Ce n’est pas forcément le cas.

En fait je fais ça dans à peu près n’importe quel langage, selon le format dans lequel je récupère les dates/heures. Si c’est des chaînes je m’embête rarement à les parser.

De toute évidence. :mrgreen:
Par curiosité, que donne ceci avec zsh :

if test "02:00:00" '<' "04:00:00"; then echo "vrai" fi

En fait je fais ça dans à peu près n’importe quel langage, selon le format dans lequel je récupère les dates/heures. Si c’est des chaînes je m’embête rarement à les parser.[/quote]
Généralement je met tout dans des structures/objets qui font ça mieux que moi.

De toute évidence. :mrgreen:
Par curiosité, que donne ceci avec zsh :

if test "02:00:00" '<' "04:00:00"; then echo "vrai" fi[/quote]
Idem.

Dingue! C’est tout simple, je n’imaginais pas bash capable de faire ça si simplement. Je n’y arrivait même pas en python (faut dire que je m’y p’tet pris comme un pied).
Bravo syam!