GNU/Linux >> Linux Esercitazione >  >> Linux

Come convertire il giorno dell'anno e l'anno in una data YYYYMMDD?

Questa funzione Bash funziona per me su un sistema basato su GNU:

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

Alcuni esempi:

$ 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

Questa funzione considera il giorno giuliano zero come l'ultimo giorno dell'anno precedente.

Ed ecco una funzione bash per sistemi basati su UNIX, come macOS:

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

Non può essere fatto solo in Bash, ma se hai 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;

Esegui info 'Date input formats' per vedere quali formati sono consentiti.

Il formato della data YYYY-DDD non sembra esserci e ci sto provando

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

mostra che non funziona, quindi penso njd è corretto, il modo migliore è utilizzare uno strumento esterno diverso da bash e date .

Se vuoi davvero usare solo bash e gli strumenti di base della riga di comando, puoi fare qualcosa del genere:

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
}

Ma è un modo piuttosto lento per farlo.

Un modo più veloce ma più complesso cerca di scorrere ogni mese, trova l'ultimo giorno di quel mese, quindi controlla se il giorno giuliano è in quell'intervallo.

# 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. Come sincronizzare data e ora dalla riga di comando in Ubuntu

  2. Come convertire da CentOS Linux 8 a CentOS Stream 8

  3. Come visualizzare la data e l'ora di riavvio del sistema Linux

  4. Come usare sched_getaffinity e sched_setaffinity in Linux da C?

  5. Come convertire un file di testo da Shift JIS a UTF-8 e viceversa dal terminale

Come eseguire l'aggiornamento a Ubuntu 16.04 da Ubuntu 14.04 e 15.10

Come trovare la data e l'ora di installazione del sistema operativo Linux

Come convertire PDF in immagini PNG e viceversa in Linux

Come impostare data e ora su Linux

Come convertire un file .pem in un file .ppk su Windows e Linux

Come modificare data, ora e fuso orario in Linux Mint 20