GNU/Linux >> LINUX-Kenntnisse >  >> Linux

Wie konvertiere ich den Tag des Jahres und das Jahr in ein Datum JJJJMMTT?

Diese Bash-Funktion funktioniert bei mir auf einem GNU-basierten System:

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

Einige Beispiele:

$ 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

Diese Funktion betrachtet den julianischen Tag Null als den letzten Tag des vorherigen Jahres.

Und hier ist eine Bash-Funktion für UNIX-basierte Systeme wie macOS:

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

Kann nicht nur in Bash gemacht werden, aber wenn Sie Perl haben:

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;

Führen Sie info 'Date input formats' aus um zu sehen, welche Formate erlaubt sind.

Das Datumsformat YYYY-DDD scheint nicht vorhanden zu sein und wird versucht

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

zeigt, dass es nicht funktioniert, also denke ich njd richtig ist, verwenden Sie am besten ein anderes externes Tool als bash und date .

Wenn Sie wirklich nur Bash und einfache Befehlszeilentools verwenden möchten, können Sie Folgendes tun:

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
}

Aber das ist ein ziemlich langsamer Weg.

Ein schnellerer, aber komplexerer Weg versucht, jeden Monat zu durchlaufen, findet den letzten Tag in diesem Monat und sieht dann, ob der julianische Tag in diesem Bereich liegt.

# 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. So synchronisieren Sie Datum und Uhrzeit über die Befehlszeile in Ubuntu

  2. So aktualisieren Sie auf Ubuntu 22.04 LTS von Ubuntu 20.04 LTS und 21.10

  3. So konvertieren Sie von CentOS Linux 8 zu CentOS Stream 8

  4. So zeigen Sie das Datum und die Uhrzeit des Neustarts des Linux-Systems an

  5. Wie verwende ich sched_getaffinity und sched_setaffinity in Linux von C aus?

So führen Sie ein Upgrade von Ubuntu 14.04 und 15.10 auf Ubuntu 16.04 durch

So finden Sie das Installationsdatum und die Uhrzeit des Linux-Betriebssystems

So konvertieren Sie PDF in PNG-Bilder und zurück unter Linux

So stellen Sie Datum und Uhrzeit unter Linux ein

So konvertieren Sie eine .pem-Datei in eine .ppk-Datei unter Windows und Linux

So ändern Sie Datum, Uhrzeit und Zeitzone in Linux Mint 20