GNU/Linux >> Tutoriels Linux >  >> Linux

Comment convertir le jour de l'année et l'année en une date AAAAMMJJ ?

Cette fonction Bash fonctionne pour moi sur un système basé sur GNU :

jul () { date -d "$1-01-01 +$2 days -1 day" "+%Y%m%d"; }

Quelques exemples :

$ y=2011; od=0; for d in {-4..4} 59 60 {364..366} 425 426; do (( d > od + 1)) && echo; printf "%3s " $d; jul $y $d; od=$d; done
 -4 20101227
 -3 20101228
 -2 20101229
 -1 20101230
  0 20101231
  1 20110101
  2 20110102
  3 20110103
  4 20110104

 59 20110228
 60 20110301

364 20111230
365 20111231
366 20120101

425 20120229
426 20120301

Cette fonction considère que le jour julien zéro est le dernier jour de l'année précédente.

Et voici une fonction bash pour les systèmes basés sur UNIX, tels que macOS :

jul () { (( $2 >=0 )) && local pre=+; date -v$pre$2d -v-1d -j -f "%Y-%m-%d" $1-01-01 +%Y%m%d; }

Cela ne peut pas être fait uniquement avec Bash, mais si vous avez Perl :

use POSIX;

my ($jday, $year) = (100, 2011);

# Unix time in seconds since Jan 1st 1970
my $time = mktime(0,0,0, $jday, 0, $year-1900);

# same thing as a list that we can use for date/time formatting
my @tm = localtime $time;

my $yyyymmdd = strftime "%Y%m%d", @tm;

Exécutez info 'Date input formats' pour voir quels formats sont autorisés.

Le format de date AAAA-JJJ ne semble pas être là, et j'essaie

$ date -d '2011-011'
date: invalid date `2011-011'

montre que cela ne fonctionne pas, donc je pense que njd est correct, le mieux est d'utiliser un outil externe autre que bash et date .

Si vous voulez vraiment n'utiliser que bash et les outils de ligne de commande de base, vous pouvez faire quelque chose comme ceci :

julian_date_to_yyyymmdd()
{
    date=$1    # assume all dates are in YYYYMMM format
    year=${date%???}
    jday=${date#$year}
    for m in `seq 1 12`; do
        for d in `seq 1 31`; do
            yyyymmdd=$(printf "%d%02d%02d" $year $m $d)
            j=$(date +"%j" -d "$yyyymmdd" 2>/dev/null)
            if test "$jday" = "$j"; then
                echo "$yyyymmdd"
                return 0
            fi
        done
    done
    echo "Invalid date" >&2
    return 1
}

Mais c'est une façon assez lente de le faire.

Un moyen plus rapide mais plus complexe essaie de parcourir chaque mois, trouve le dernier jour de ce mois, puis voit si le jour julien se trouve dans cette plage.

# year_month_day_to_jday <year> <month> <day> => <jday>
# returns 0 if date is valid, non-zero otherwise
# year_month_day_to_jday 2011 2 1 => 32
# year_month_day_to_jday 2011 1 32 => error
year_month_day_to_jday()
{
    # XXX use local or typeset if your shell supports it
    _s=$(printf "%d%02d%02d" "$1" "$2" "$3")
    date +"%j" -d "$_s"
}

# last_day_of_month_jday <year> <month>
# last_day_of_month_jday 2011 2 => 59
last_day_of_month_jday()
{
    # XXX use local or typeset if you have it
    _year=$1
    _month=$2
    _day=31

    # GNU date exits with 0 if day is valid, non-0 if invalid
    # try counting down from 31 until we find the first valid date
    while test $_day -gt 0; do
        if _jday=$(year_month_day_to_jday $_year $_month $_day 2>/dev/null); then
            echo "$_jday"
            return 0
        fi
        _day=$((_day - 1))
    done
    echo "Invalid date" >&2
    return 1
}

# first_day_of_month_jday <year> <month>
# first_day_of_month_jday 2011 2 => 32
first_day_of_month_jday()
{
    # XXX use local or typeset if you have it
    _year=$1
    _month=$2
    _day=1

    if _jday=$(year_month_day_to_jday $_year $_month 1); then
        echo "$_jday"
        return 0
    else
        echo "Invalid date" >&2
        return 1
    fi
}

# julian_date_to_yyyymmdd <julian day> <4-digit year>
# e.g. julian_date_to_yyyymmdd 32 2011 => 20110201
julian_date_to_yyyymmdd()
{
    jday=$1
    year=$2

    for m in $(seq 1 12); do
        endjday=$(last_day_of_month_jday $year $m)
        if test $jday -le $endjday; then
            startjday=$(first_day_of_month_jday $year $m)
            d=$((jday - startjday + 1))
            printf "%d%02d%02d\n" $year $m $d
            return 0
        fi
    done
    echo "Invalid date" >&2
    return 1
}

Linux
  1. Comment synchroniser la date et l'heure à partir de la ligne de commande dans Ubuntu

  2. Comment convertir CentOS Linux 8 en CentOS Stream 8

  3. Comment afficher la date et l'heure de redémarrage du système Linux

  4. Comment convertir un fichier texte de Shift JIS en UTF-8 et inversement depuis le terminal

  5. Comment puis-je ajouter X jours à ce jour et obtenir une nouvelle date ?

Comment mettre à niveau vers Ubuntu 16.04 à partir d'Ubuntu 14.04 et 15.10

Comment trouver la date et l'heure d'installation du système d'exploitation Linux

Comment convertir un PDF en images PNG et inversement sous Linux

Comment définir la date et l'heure sous Linux

Comment convertir un fichier .pem en un fichier .ppk sous Windows et Linux

Comment changer la date, l'heure et le fuseau horaire dans Linux Mint 20