Comment tester si une variable est un nombre en Bash?

je ne peux pas comprendre comment faire un argument transmis à mon script est un nombre ou pas.

Tout ce que je veux faire, c'est quelque chose comme ça:

test *isnumber*  && VAR= || echo "need a number"

de l'aide?

454
demandé sur codeforester 2009-04-30 17:30:16

30 réponses

Une approche consiste à utiliser une expression régulière, comme suit:

re='^[0-9]+$'
if ! [[ $yournumber =~ $re ]] ; then
   echo "error: Not a number" >&2; exit 1
fi

si la valeur n'est pas nécessairement un entier, envisager de modifier le regex de manière appropriée; par exemple:

^[0-9]+([.][0-9]+)?$

...ou, pour manipuler des nombres avec un signe:

^[+-]?[0-9]+([.][0-9]+)?$
609
répondu Charles Duffy 2018-08-26 00:40:36

sans bashismes (fonctionne même dans le système V sh),

case $string in
    ''|*[!0-9]*) echo bad ;;
    *) echo good ;;
esac

ceci rejette les chaînes vides et les chaînes contenant des non-chiffres, acceptant tout le reste.

les nombres négatifs ou à virgule flottante ont besoin de travaux supplémentaires. Une idée est d'exclure - / . dans le premier motif" mauvais " et d'ajouter d'autres motifs "mauvais" contenant les utilisations inappropriées d'eux ( ?*-* / *.*.* )

217
répondu jilles 2010-10-16 22:56:11

la solution suivante peut également être utilisée dans les shells de base comme Bourne sans avoir besoin d'expressions régulières. Fondamentalement, toute opération d'évaluation de valeur numérique utilisant des non-nombres résultera en une erreur qui sera implicitement considérée comme fausse dans shell:

"$var" -eq "$var"

comme dans:

#!/bin/bash

var=a

if [ -n "$var" ] && [ "$var" -eq "$var" ] 2>/dev/null; then
  echo number
else
  echo not a number
fi

vous pouvez également tester pour $? le code de retour de l'opération qui est plus explicite:

[ -n "$var" ] && ["$var" -eq "$var"] 2>/dev/null
if [ $? -ne 0 ]; then
   echo $var is not number
fi

La Redirection de l'erreur standard est là pour cacher le message "integer expression expected" que bash imprime au cas où nous n'aurions pas de nombre.

mises en garde (merci aux commentaires ci-dessous):

  • les nombres avec des points décimaux sont et non identifiés comme des "nombres" valides
  • en utilisant [[ ]] au lieu de [ ] sera toujours évaluer à true
  • la plupart des coquilles Non-Bash évalueront toujours cette expression comme true
  • le comportement à Bash n'est pas documenté et peut donc changer sans avertissement
  • si la valeur inclut des espaces après le nombre (par exemple "1 a") produit une erreur, comme bash: [[: 1 a: syntax error in expression (error token is "a")
  • si la valeur est la même que var-name( par exemple i= "i"), produit une erreur, comme bash: [[: i: expression recursion level exceeded (error token is "i")
148
répondu Alberto Zaccagni 2018-09-04 07:41:25

ce test si un nombre est un entier non négatif et est à la fois indépendant de la coquille (c.-à-d. sans bashismes) et utilise seulement shell intégré:

[ -z "${num##[0-9]*}" ] && echo "is a number" || echo "is not a number";

MAIS EST ERRONÉ .

Comme jilles commenté et suggéré dans sa réponse c'est la bonne façon de le faire en utilisant shell-patterns.

[ ! -z "${num##*[!0-9]*}" ] && echo "is a number" || echo "is not a number";
32
répondu mrucci 2017-05-23 11:47:30

je suis surpris par les solutions qui analysent directement les formats de nombres dans shell. shell n'est pas bien adapté à cela, étant un DSL pour le contrôle des fichiers et des processus. Il y a de nombreux parsers un peu plus bas, par exemple:

isdecimal() {
  # filter octal/hex/ord()
  num=$(printf '%s' "" | sed "s/^0*\([1-9]\)//; s/'/^/")

  test "$num" && printf '%f' "$num" >/dev/null 2>&1
}

changez '%f ' à n'importe quel format particulier dont vous avez besoin.

27
répondu pixelbeat 2015-02-15 12:37:08

Personne n'a suggéré bash extended pattern matching :

[[  == ?(-)+([0-9]) ]] && echo " is an integer"
25
répondu glenn jackman 2015-02-13 19:49:44

je regardais les réponses et... réalisé que personne ne pensait à des nombres flottants (avec point)!

en utilisant grep est grand aussi.

-E means extended regexp

- q signifie calme (sans écho)

-qE est la combinaison des deux.

pour tester directement en ligne de commande:

$ echo "32" | grep -E ^\-?[0-9]?\.?[0-9]+$  
# answer is: 32

$ echo "3a2" | grep -E ^\-?[0-9]?\.?[0-9]+$  
# answer is empty (false)

$ echo ".5" | grep -E ^\-?[0-9]?\.?[0-9]+$  
# answer .5

$ echo "3.2" | grep -E ^\-?[0-9]?\.?[0-9]+$  
# answer is 3.2

Utilisation dans un script bash:

check=`echo "" | grep -E ^\-?[0-9]*\.?[0-9]+$`

if [ "$check" != '' ]; then    
  # it IS numeric
  echo "Yeap!"
else
  # it is NOT numeric.
  echo "nooop"
fi

pour faire correspondre juste des entiers, utilisez ceci:

# change check line to:
check=`echo "" | grep -E ^\-?[0-9]+$`
13
répondu Sergio Abreu 2016-12-20 02:30:28

juste une suite à @mary. Mais parce que je n'ai pas assez de rep, ne pourrait pas poster ceci comme un commentaire à ce post. Bref, voici ce que j'ai utilisé:

isnum() { awk -v a="" 'BEGIN {print (a == a + 0)}'; }

La fonction retourne 1 si l'argument est un nombre, sinon retourne "0". Cela fonctionne pour les entiers ainsi que des flotteurs. L'utilisation est quelque chose comme:

n=-2.05e+07
res=`isnum "$n"`
if [ "$res" == "1" ]; then
     echo "$n is a number"
else
     echo "$n is not a number"
fi
11
répondu triple_r 2015-02-13 21:11:22

http://tldp.org/LDP/Bash-Beginners-Guide/html/sect_04_03.html

vous pouvez également utiliser les classes de caractères de bash.

if [[ $VAR = *[[:digit:]]* ]]; then
 echo "$VAR is numeric"
else
 echo "$VAR is not numeric"
fi

les chiffres comprendront l'espace, le point décimal et" e "ou" E " pour la virgule flottante.

mais, si vous spécifiez un nombre hexadécimal de style C, i.e." 0xffff "ou" 0XFFFFFF", [[: digit:]] retourne true. Un peu d'un piège ici, bash vous permet de faire quelque chose comme "0xAZ00" et encore comptez - le comme un chiffre (n'est-ce pas d'une bizarrerie de compilateurs GCC qui vous permettent d'utiliser la notation 0x pour des bases autres que 16???)

vous pourriez vouloir tester pour" 0x "ou" 0X " avant de tester si c'est un numérique si votre entrée est complètement non fiable, sauf si vous voulez accepter des nombres hexadécimaux. Cela serait accompli par:

if [[ ${VARIABLE:1:2} = "0x" ]] || [[ ${VARIABLE:1:2} = "0X" ]]; then echo "$VAR is not numeric"; fi
7
répondu ultrasawblade 2010-06-12 14:52:19

vieille question, mais je voulais juste prendre ma solution. Celui-ci n'a pas besoin de tours de coquillage étranges, ou de compter sur quelque chose qui n'a pas été autour pour toujours.

if [ -n "$(printf '%s\n' "$var" | sed 's/[0-9]//g')" ]; then
    echo 'is not numeric'
else
    echo 'is numeric'
fi

essentiellement, il supprime tous les chiffres de l'entrée, et si vous êtes laissé avec une chaîne de longueur non-zéro alors ce n'était pas un nombre.

6
répondu Sammitch 2015-02-13 21:44:37

je voudrais essayer ceci:

printf "%g" "$var" &> /dev/null
if [[ $? == 0 ]] ; then
    echo "$var is a number."
else
    echo "$var is not a number."
fi

Note: Ceci reconnaît nan et inf comme nombre.

5
répondu overflowed 2012-10-08 22:43:41

ne peut pas encore commenter donc je vais ajouter ma propre réponse, qui est une extension à la réponse de glenn jackman en utilisant bash pattern matching.

mon premier besoin était d'identifier les nombres et de distinguer les entiers et les flotteurs. Les définitions de fonction déduites à:

function isInteger() {
    [[  == ?(-)+([0-9]) ]]
}

function isFloat() {
    [[  == ?(-)@(+([0-9]).*([0-9])|*([0-9]).+([0-9]))?(E?(-|+)+([0-9])) ]]
}

j'ai utilisé le test à l'unité (avec shUnit2) pour valider mes modèles ont fonctionné comme prévu:

oneTimeSetUp() {
    int_values="0 123 -0 -123"
    float_values="0.0 0. .0 -0.0 -0. -.0 \
        123.456 123. .456 -123.456 -123. -.456
        123.456E08 123.E08 .456E08 -123.456E08 -123.E08 -.456E08 \
        123.456E+08 123.E+08 .456E+08 -123.456E+08 -123.E+08 -.456E+08 \
        123.456E-08 123.E-08 .456E-08 -123.456E-08 -123.E-08 -.456E-08"
}

testIsIntegerIsFloat() {
    local value
    for value in ${int_values}
    do
        assertTrue "${value} should be tested as integer" "isInteger ${value}"
        assertFalse "${value} should not be tested as float" "isFloat ${value}"
    done

    for value in ${float_values}
    do
        assertTrue "${value} should be tested as float" "isFloat ${value}"
        assertFalse "${value} should not be tested as integer" "isInteger ${value}"
    done

}

Notes: le modèle isFloat peut être modifié pour être plus tolérant le point décimal ( @(.,) ) et le symbole E ( @(Ee) ). Mes tests unitaires ne testent que les valeurs qui sont soit integer ou float, mais pas n'importe quelle entrée invalide.

5
répondu karttu 2015-03-24 13:59:53
[[  =~ ^-?[0-9]+$ ]] && echo "number"

N'oubliez pas - pour inclure les nombres négatifs!

4
répondu D_I 2017-11-12 05:15:14

j'utilise expr . Elle renvoie une valeur non nulle si vous essayez d'ajouter un zéro à une valeur non numérique:

if expr $number + 0 > /dev/null 2>&1
then
    echo "$number is a number"
else
    echo "$number isn't a number"
fi

il pourrait être possible d'utiliser bc si vous avez besoin de non-entiers, mais je ne crois pas que bc a tout à fait le même comportement. Ajouter zéro à un non-nombre vous donne zéro et il retourne une valeur de zéro aussi. Peut-être Pouvez-vous combiner bc et expr . Utilisez bc pour ajouter zéro à $number . Si la réponse est 0 , alors essayez expr pour vérifier que $number n'est pas zéro.

3
répondu David W. 2013-10-27 03:45:01
test -z "${i//[0-9]}" && echo digits || echo no no no

${i//[0-9]} remplace tout chiffre de la valeur de $i par une chaîne vide, voir man -P 'less +/parameter\/' bash . -z vérifie si la chaîne résultante a une longueur nulle.

si vous voulez aussi exclure le cas où $i est vide, vous pouvez utiliser une de ces constructions:

test -n "$i" && test -z "${i//[0-9]}" && echo digits || echo not a number
[[ -n "$i" && -z "${i//[0-9]}" ]] && echo digits || echo not a number
3
répondu user2683246 2014-11-05 16:46:24

la façon La plus simple est de vérifier s'il contient des caractères numériques. Vous remplacez tous les caractères numériques par rien et vérifiez la longueur. S'il y a de la longueur, ce n'est pas un nombre.

if [[ ! -n ${input//[0-9]/} ]]; then
    echo "Input Is A Number"
fi
3
répondu Andrew Anthony Gerst 2015-07-27 17:21:51

une réponse claire a déjà été donnée par @charles Dufy et d'autres. Une solution de bash pure serait d'utiliser ce qui suit :

string="-12,345"
if [[ "$string" =~ ^-?[0-9]+[.,]?[0-9]*$ ]]
then
    echo $string is a number
else
    echo $string is not a number
fi

bien que pour les nombres réels il n'est pas obligatoire d'avoir un nombre avant le point radix .

pour fournir un support plus complet des nombres flottants et de la notation scientifique (de nombreux programmes dans C / Fortran ou autrement exporteront flottant de cette façon), un ajout utile à cette ligne serait ce qui suit :

string="1.2345E-67"
if [[ "$string" =~ ^-?[0-9]*[.,]?[0-9]*[eE]?-?[0-9]+$ ]]
then
    echo $string is a number
else
    echo $string is not a number
fi

permettant ainsi de différencier les types de numéros, si vous cherchez un type spécifique:

string="-12,345"
if [[ "$string" =~ ^-?[0-9]+$ ]]
then
    echo $string is an integer
elif [[ "$string" =~ ^-?[0-9]*[.,]?[0-9]*$ ]]
then
    echo $string is a float
elif [[ "$string" =~ ^-?[0-9]*[.,]?[0-9]*[eE]-?[0-9]+$ ]]
then
    echo $string is a scientific number
else
    echo $string is not a number
fi

Note: Nous pourrions énumérer les exigences syntaxiques pour la notation décimale et scientifique, une étant d'autoriser virgule comme point radix, ainsi que ".". Nous affirmerions alors qu'il ne doit y avoir qu'un seul point radix. Il peut y avoir deux signes +/- dans un flotteur [Ee]. J'ai appris quelques règles de plus de la part D'Aulu's travail, et testé contre de mauvaises chaînes telles que " '-' '-E-1' '0-0'. Voici mes outils regex / substring / expr qui semblent tenir le coup:

parse_num() {
 local r=`expr "" : '.*\([.,]\)' 2>/dev/null | tr -d '\n'` 
 nat='^[+-]?[0-9]+[.,]?$' \
 dot="${1%[.,]*}${r}${1##*[.,]}" \
 float='^[\+\-]?([.,0-9]+[Ee]?[-+]?|)[0-9]+$'
 [[ "" == $dot ]] && [[ "" =~ $float ]] || [[ "" =~ $nat ]]
} # usage: parse_num -123.456
3
répondu Aulo 2016-07-06 08:47:19

comme j'ai dû toucher avec ce dernièrement et comme karttu appoach avec l'unité test le plus. J'ai révisé le code et ajouté d'autres solutions, essayez-le vous-même pour voir les résultats:

#!/bin/bash

    # N={0,1,2,3,...} by syntaxerror
function isNaturalNumber()
{
 [[  =~ ^[0-9]+$ ]]
}
    # Z={...,-2,-1,0,1,2,...} by karttu
function isInteger() 
{
 [[  == ?(-)+([0-9]) ]]
}
    # Q={...,-½,-¼,0.0,¼,½,...} by karttu
function isFloat() 
{
 [[  == ?(-)@(+([0-9]).*([0-9])|*([0-9]).+([0-9]))?(E?(-|+)+([0-9])) ]]
}
    # R={...,-1,-½,-¼,0.E+n,¼,½,1,...}
function isNumber()
{
 isNaturalNumber  || isInteger  || isFloat 
}

bools=("TRUE" "FALSE")
int_values="0 123 -0 -123"
float_values="0.0 0. .0 -0.0 -0. -.0 \
    123.456 123. .456 -123.456 -123. -.456 \
    123.456E08 123.E08 .456E08 -123.456E08 -123.E08 -.456E08 \
    123.456E+08 123.E+08 .456E+08 -123.456E+08 -123.E+08 -.456E+08 \
    123.456E-08 123.E-08 .456E-08 -123.456E-08 -123.E-08 -.456E-08"
false_values="blah meh mooh blah5 67mooh a123bc"

for value in ${int_values} ${float_values} ${false_values}
do
    printf "  %5s=%-30s" $(isNaturalNumber $value) ${bools[$?]} $(printf "isNaturalNumber(%s)" $value)
    printf "%5s=%-24s" $(isInteger $value) ${bools[$?]} $(printf "isInteger(%s)" $value)
    printf "%5s=%-24s" $(isFloat $value) ${bools[$?]} $(printf "isFloat(%s)" $value)
    printf "%5s=%-24s\n" $(isNumber $value) ${bools[$?]} $(printf "isNumber(%s)" $value)
done

Donc isNumber() comprend des tirets, des virgules et notation exponentielle et, par conséquent, renvoie la valeur TRUE sur des entiers et des flotteurs où, d'autre part isFloat() retourne FALSE en valeurs entières et isInteger () retourne également FALSE sur floats. Pour votre confort tout en un liners:

isNaturalNumber() { [[  =~ ^[0-9]+$ ]]; }
isInteger() { [[  == ?(-)+([0-9]) ]]; }
isFloat() { [[  == ?(-)@(+([0-9]).*([0-9])|*([0-9]).+([0-9]))?(E?(-|+)+([0-9])) ]]; }
isNumber() { isNaturalNumber  || isInteger  || isFloat ; }
2
répondu 3ronco 2016-11-06 11:30:36

j'utilise ce qui suit (pour les entiers):

## ##### constants
##
## __TRUE - true (0)
## __FALSE - false (1)
##
typeset -r __TRUE=0
typeset -r __FALSE=1

## --------------------------------------
## isNumber
## check if a value is an integer 
## usage: isNumber testValue 
## returns: ${__TRUE} - testValue is a number else not
##
function isNumber {
  typeset TESTVAR="$(echo "" | sed 's/[0-9]*//g' )"
  [ "${TESTVAR}"x = ""x ] && return ${__TRUE} || return ${__FALSE}
}

isNumber  
if [ $? -eq ${__TRUE} ] ; then
  print "is a number"
fi
1
répondu Marnix 2009-05-04 12:50:42

j'ai essayé la recette de ultrasawblade car elle me semblait la plus pratique, et je n'ai pas pu la faire fonctionner. En fin de Compte j'ai conçu une autre façon cependant, basée comme d'autres dans la substitution de paramètre, cette fois avec le remplacement de regex:

[[ "${var//*([[:digit:]])}" ]]; && echo "$var is not numeric" || echo "$var is numeric"

il supprime tous les caractères :digit: class dans $var et vérifie si nous sommes laissés avec une chaîne vide, ce qui signifie que l'original était seulement des nombres.

Ce que j'aime c'est son faible encombrement et flexibilité. Sous cette forme, il ne fonctionne que pour les entiers de base 10 non délimités, bien que vous puissiez sûrement utiliser l'appariement de motif pour l'adapter à d'autres besoins.

1
répondu ata 2010-10-16 22:37:30

Quick & Dirty: je sais que ce n'est pas la façon la plus élégante, mais j'ai l'habitude de simplement ajouté un zéro et de tester le résultat. comme ceci:

function isInteger {
  [ $((+0)) != 0 ] && echo " is a number" || echo " is not a number"
 }

x=1;      isInteger $x
x="1";    isInteger $x
x="joe";  isInteger $x
x=0x16 ;  isInteger $x
x=-32674; isInteger $x   

$(($1+0)) renvoie 0 ou bombe si $1 n'est PAS un entier. par exemple:

function zipIt  { # quick zip - unless the 1st parameter is a number
  ERROR="not a valid number. " 
  if [ $((+0)) != 0 ] ; then  # isInteger() 
      echo " backing up files changed in the last  days."
      OUT="zipIt--day.tgz" 
      find . -mtime - -type f -print0 | xargs -0 tar cvzf $OUT 
      return 1
  fi
    showError $ERROR
}

NOTE: je suppose que je n'ai jamais pensé à vérifier les flotteurs ou les types mixtes qui feront toute la bombe de script... dans mon cas, je ne voulais pas aller plus loin. Je vais jouer avec mrucci solution et Duffy regex-ils semblent les plus robustes dans le cadre de bash...

1
répondu WWWIZARDS 2010-12-24 06:02:38

j'ai trouvé une version assez courte:

function isnum()
{
    return `echo "" | awk -F"\n" '{print ("151900920" != "151900920"+0)}'`
}
1
répondu mary 2012-02-13 14:07:44
  • variable à vérifier

    number=12345 ou number=-23234 ou number=23.167 ou number=-345.234

  • contrôle numérique ou non numérique

    echo $number | grep -E '^-?[0-9]*\.?[0-9]*$' > /dev/null

  • décider des mesures à prendre en se fondant sur le statut de sortie de la ci-dessus

    if [ $? -eq 0 ]; then echo "Numeric"; else echo "Non-Numeric"; fi

1
répondu Atanu 2012-09-28 18:21:50

pour attraper les nombres négatifs:

if [[  == ?(-)+([0-9.]) ]]
    then
    echo number
else
    echo not a number
fi
1
répondu user28490 2013-03-04 17:10:49

vous pouvez utiliser " let "aussi comme ceci:

[ ~]$ var=1
[ ~]$ let $var && echo "It's a number" || echo "It's not a number"
It\'s a number
[ ~]$ var=01
[ ~]$ let $var && echo "It's a number" || echo "It's not a number"
It\'s a number
[ ~]$ var=toto
[ ~]$ let $var && echo "It's a number" || echo "It's not a number"
It\'s not a number
[ ~]$ 

mais je préfère utiliser l'opérateur "= ~ " Bash 3+ comme quelques réponses dans ce thread.

1
répondu Idriss Neumann 2013-10-27 09:57:37

j'utilise printf comme autres réponses mentionnées, si vous fournissez la chaîne de format" %f "ou" %i " printf fera la vérification pour vous. Plus facile que de réinventer les contrôles, la syntaxe est simple et courte et printf est omniprésent. Si ses un bon choix à mon avis - vous pouvez également utiliser l'idée suivante pour vérifier un certain nombre de choses, ce n'est pas seulement utile pour vérifier les nombres.

declare  -r CHECK_FLOAT="%f"  
declare  -r CHECK_INTEGER="%i"  

 ## <arg 1> Number - Number to check  
 ## <arg 2> String - Number type to check  
 ## <arg 3> String - Error message  
function check_number() { 
  local NUMBER="" 
  local NUMBER_TYPE="" 
  local ERROR_MESG=""
  local -i PASS=1 
  local -i FAIL=0   
  case "${NUMBER_TYPE}" in 
    "${CHECK_FLOAT}") 
        if ((! $(printf "${CHECK_FLOAT}" "${NUMBER}" &>/dev/random;echo $?))); then 
           echo "${PASS}"
        else 
           echo "${ERROR_MESG}" 1>&2
           echo "${FAIL}"
        fi 
        ;;                 
    "${CHECK_INTEGER}") 
        if ((! $(printf "${CHECK_INTEGER}" "${NUMBER}" &>/dev/random;echo $?))); then 
           echo "${PASS}"
        else 
           echo "${ERROR_MESG}" 1>&2
           echo "${FAIL}"
        fi 
        ;;                 
                     *) 
        echo "Invalid number type format: ${NUMBER_TYPE} to check_number()." 1>&2
        echo "${FAIL}"
        ;;                 
   esac
} 

>$ var=45

>$ (($(check_number $var "${CHECK_INTEGER}" "Error: Found $var - An integer is required."))) && { echo "$var+5" | bc; }

1
répondu 2015-03-09 17:05:21

j'aime la réponse d'Alberto Zaccagni.

if [ "$var" -eq "$var" ] 2>/dev/null; then

conditions préalables importantes: - pas de sous-coquille donné naissance à - pas de RE analyseurs invoquée - la plupart des applications shell n'utilisent pas de nombres réels

mais si $var est complexe (par exemple un accès au tableau associatif), et si le nombre sera un entier non négatif (la plupart des cas d'utilisation), alors c'est peut-être plus efficace?

if [ "$var" -ge 0 ] 2> /dev/null; then ..
1
répondu user3895088 2015-09-30 10:03:49
printf '%b' "-123\nABC" | tr '[:space:]' '_' | grep -q '^-\?[[:digit:]]\+$' && echo "Integer." || echo "NOT integer."

supprimer le -\? dans grep matching pattern si vous n'acceptez pas un nombre entier négatif.

1
répondu Ane Dijitak 2016-01-06 09:27:16

faisant suite à réponse de David W d'Octobre '13, si en utilisant expr ce pourrait être mieux

test_var=`expr $am_i_numeric \* 0` >/dev/null 2>&1
if [ "$test_var" = "" ]
then
    ......

si numérique, multiplié par 1 vous donne la même valeur, (y compris les nombres négatifs). Sinon vous obtenez null que vous pouvez tester pour

1
répondu Jon T 2016-04-26 15:23:07

a fait la même chose ici avec une expression régulière qui teste la partie entière et la partie décimale, séparées par un point.

re="^[0-9]*[.]{0,1}[0-9]*$"

if [[  =~ $re ]] 
then
   echo "is numeric"
else
  echo "Naahh, not numeric"
fi
1
répondu Jerome 2018-05-06 21:27:31