Znalezienie maksymalnej poprawnej daty w printf

Podczas pisania tego kursu/poradnika dużym zaskoczeniem dla mnie było to, że funkcja bash printf potrafi wypisywać datę w takie sposób jak strftime na podstawie argumentu takiego jak EPOCH.

Postanowiłem sprawdzić jak daleko owa data może wybiegać w przyszłość, oraz czy jest jakaś magiczna granica jak kiedyś „mityczny rok 2000”.

Poniższy skrypt szuka maksymalnej poprawnej daty.

#!/bin/bash

{
    INCREMENT=`printf "1%017d" 0`
    START_DATE=`printf "%(%s)T" -1`
    for (( num=${START_DATE} ; ; num+=${INCREMENT} )) ; do

        MDATE=`printf '%(%Y-%m-%d %H:%M:%S %Z)T' "$num"`

        if [[ "${MDATE:0:4}" -eq "1970" || "${MDATE:0:2}" -eq "-2" ]] ; then

            if [ "${#LAST_INCREMENT}" -gt "${#INCREMENT}" ] ; then
                LAST_INCREMENT=${INCREMENT}
                echo "EXCEP: ${LAST_MDATE} (${LAST_OK} + $LAST_INCREMENT ($INCREMENT)))"
            fi

            if [ ${#LAST_INCREMENT} -eq "1" ] ; then
                echo "FOUND: ${LAST_MDATE} (${LAST_OK} + $LAST_INCREMENT)"
                break
            fi

            num=${LAST_OK}
            INCREMENT=${INCREMENT:0:$(( ${#INCREMENT} - 1))}
        else
            LAST_OK=$num
            LAST_INCREMENT=$INCREMENT
            LAST_MDATE=$MDATE
            echo "CHECK: ${LAST_MDATE} (${LAST_OK} + $LAST_INCREMENT)"
        fi
    done
}

Wynik uruchomienia kodu, który sprawdzi przepełnienie INT32 w polu ROK w funkcji powłoki printf.

CHECK: 2019-02-10 19:03:59 CET (1549821839 + 100000000000000000)
CHECK: 316889404-03-07 12:50:39 CET (10000001549821839 + 10000000000000000)
CHECK: 633776789-04-01 06:37:19 CET (20000001549821839 + 10000000000000000)
CHECK: 950664174-04-26 00:23:59 CET (30000001549821839 + 10000000000000000)
CHECK: 1267551559-05-21 18:10:39 CET (40000001549821839 + 10000000000000000)
CHECK: 1584438944-06-14 11:57:19 CET (50000001549821839 + 10000000000000000)
CHECK: 1901326329-07-10 05:43:59 CET (60000001549821839 + 10000000000000000)
CHECK: 1933015068-01-11 07:30:39 CET (61000001549821839 + 1000000000000000)
CHECK: 1964703806-07-15 09:17:19 CET (62000001549821839 + 1000000000000000)
CHECK: 1996392545-01-15 11:03:59 CET (63000001549821839 + 1000000000000000)
CHECK: 2028081283-07-19 12:50:39 CET (64000001549821839 + 1000000000000000)
CHECK: 2059770022-01-20 14:37:19 CET (65000001549821839 + 1000000000000000)
CHECK: 2091458760-07-24 16:23:59 CET (66000001549821839 + 1000000000000000)
CHECK: 2123147499-01-25 18:10:39 CET (67000001549821839 + 1000000000000000)
CHECK: 2126316372-12-02 03:57:19 CET (67100001549821839 + 100000000000000)
CHECK: 2129485246-10-08 13:43:59 CET (67200001549821839 + 100000000000000)
CHECK: 2132654120-08-14 23:30:39 CET (67300001549821839 + 100000000000000)
CHECK: 2135822994-06-21 09:17:19 CET (67400001549821839 + 100000000000000)
CHECK: 2138991868-04-27 19:03:59 CET (67500001549821839 + 100000000000000)
CHECK: 2142160742-03-05 04:50:39 CET (67600001549821839 + 100000000000000)
CHECK: 2145329616-01-09 14:37:19 CET (67700001549821839 + 100000000000000)
CHECK: 2145646503-05-30 08:23:59 CET (67710001549821839 + 10000000000000)
CHECK: 2145963390-10-17 02:10:39 CET (67720001549821839 + 10000000000000)
CHECK: 2146280278-03-06 19:57:19 CET (67730001549821839 + 10000000000000)
CHECK: 2146597165-07-25 13:43:59 CET (67740001549821839 + 10000000000000)
CHECK: 2146914052-12-12 07:30:39 CET (67750001549821839 + 10000000000000)
CHECK: 2147230940-05-02 01:17:19 CET (67760001549821839 + 10000000000000)
CHECK: 2147262629-01-27 03:03:59 CET (67761001549821839 + 1000000000000)
CHECK: 2147294317-10-24 04:50:39 CET (67762001549821839 + 1000000000000)
CHECK: 2147326006-07-20 06:37:19 CET (67763001549821839 + 1000000000000)
CHECK: 2147357695-04-15 08:23:59 CET (67764001549821839 + 1000000000000)
CHECK: 2147389384-01-10 10:10:39 CET (67765001549821839 + 1000000000000)
CHECK: 2147421072-10-06 11:57:19 CET (67766001549821839 + 1000000000000)
CHECK: 2147452761-07-03 13:43:59 CET (67767001549821839 + 1000000000000)
CHECK: 2147455930-05-18 23:30:39 CET (67767101549821839 + 100000000000)
CHECK: 2147459099-04-02 09:17:19 CET (67767201549821839 + 100000000000)
CHECK: 2147462268-02-15 19:03:59 CET (67767301549821839 + 100000000000)
CHECK: 2147465436-12-31 04:50:39 CET (67767401549821839 + 100000000000)
CHECK: 2147468605-11-15 14:37:19 CET (67767501549821839 + 100000000000)
CHECK: 2147471774-09-30 00:23:59 CET (67767601549821839 + 100000000000)
CHECK: 2147474943-08-15 10:10:39 CET (67767701549821839 + 100000000000)
CHECK: 2147478112-06-29 19:57:19 CET (67767801549821839 + 100000000000)
CHECK: 2147481281-05-14 05:43:59 CET (67767901549821839 + 100000000000)
CHECK: 2147481598-04-03 23:30:39 CET (67767911549821839 + 10000000000)
CHECK: 2147481915-02-22 17:17:19 CET (67767921549821839 + 10000000000)
CHECK: 2147482232-01-12 11:03:59 CET (67767931549821839 + 10000000000)
CHECK: 2147482548-12-01 04:50:39 CET (67767941549821839 + 10000000000)
CHECK: 2147482865-10-20 22:37:19 CET (67767951549821839 + 10000000000)
CHECK: 2147483182-09-10 16:23:59 CET (67767961549821839 + 10000000000)
CHECK: 2147483499-07-31 10:10:39 CET (67767971549821839 + 10000000000)
CHECK: 2147483531-04-09 11:57:19 CET (67767972549821839 + 1000000000)
CHECK: 2147483562-12-16 13:43:59 CET (67767973549821839 + 1000000000)
CHECK: 2147483594-08-24 15:30:39 CET (67767974549821839 + 1000000000)
CHECK: 2147483626-05-02 17:17:19 CET (67767975549821839 + 1000000000)
CHECK: 2147483629-07-03 03:03:59 CET (67767975649821839 + 100000000)
CHECK: 2147483632-09-02 12:50:39 CET (67767975749821839 + 100000000)
CHECK: 2147483635-11-03 22:37:19 CET (67767975849821839 + 100000000)
CHECK: 2147483639-01-04 08:23:59 CET (67767975949821839 + 100000000)
CHECK: 2147483642-03-06 18:10:39 CET (67767976049821839 + 100000000)
CHECK: 2147483645-05-07 03:57:19 CET (67767976149821839 + 100000000)
CHECK: 2147483645-08-30 21:43:59 CET (67767976159821839 + 10000000)
CHECK: 2147483645-12-24 15:30:39 CET (67767976169821839 + 10000000)
CHECK: 2147483646-04-19 09:17:19 CET (67767976179821839 + 10000000)
CHECK: 2147483646-08-13 03:03:59 CET (67767976189821839 + 10000000)
CHECK: 2147483646-12-06 20:50:39 CET (67767976199821839 + 10000000)
CHECK: 2147483647-04-01 14:37:19 CET (67767976209821839 + 10000000)
CHECK: 2147483647-07-26 08:23:59 CET (67767976219821839 + 10000000)
CHECK: 2147483647-11-19 02:10:39 CET (67767976229821839 + 10000000)
CHECK: 2147483647-11-30 15:57:19 CET (67767976230821839 + 1000000)
CHECK: 2147483647-12-12 05:43:59 CET (67767976231821839 + 1000000)
CHECK: 2147483647-12-23 19:30:39 CET (67767976232821839 + 1000000)
CHECK: 2147483647-12-24 23:17:19 CET (67767976232921839 + 100000)
CHECK: 2147483647-12-26 03:03:59 CET (67767976233021839 + 100000)
CHECK: 2147483647-12-27 06:50:39 CET (67767976233121839 + 100000)
CHECK: 2147483647-12-28 10:37:19 CET (67767976233221839 + 100000)
CHECK: 2147483647-12-29 14:23:59 CET (67767976233321839 + 100000)
CHECK: 2147483647-12-30 18:10:39 CET (67767976233421839 + 100000)
CHECK: 2147483647-12-31 21:57:19 CET (67767976233521839 + 100000)
EXCEP: 2147483647-12-31 21:57:19 CET (67767976233521839 + 10000 (10000)))
CHECK: 2147483647-12-31 22:13:59 CET (67767976233522839 + 1000)
CHECK: 2147483647-12-31 22:30:39 CET (67767976233523839 + 1000)
CHECK: 2147483647-12-31 22:47:19 CET (67767976233524839 + 1000)
CHECK: 2147483647-12-31 23:03:59 CET (67767976233525839 + 1000)
CHECK: 2147483647-12-31 23:20:39 CET (67767976233526839 + 1000)
CHECK: 2147483647-12-31 23:37:19 CET (67767976233527839 + 1000)
CHECK: 2147483647-12-31 23:53:59 CET (67767976233528839 + 1000)
CHECK: 2147483647-12-31 23:55:39 CET (67767976233528939 + 100)
CHECK: 2147483647-12-31 23:57:19 CET (67767976233529039 + 100)
CHECK: 2147483647-12-31 23:58:59 CET (67767976233529139 + 100)
CHECK: 2147483647-12-31 23:59:09 CET (67767976233529149 + 10)
CHECK: 2147483647-12-31 23:59:19 CET (67767976233529159 + 10)
CHECK: 2147483647-12-31 23:59:29 CET (67767976233529169 + 10)
CHECK: 2147483647-12-31 23:59:39 CET (67767976233529179 + 10)
CHECK: 2147483647-12-31 23:59:49 CET (67767976233529189 + 10)
CHECK: 2147483647-12-31 23:59:59 CET (67767976233529199 + 10)
EXCEP: 2147483647-12-31 23:59:59 CET (67767976233529199 + 1 (1)))
FOUND: 2147483647-12-31 23:59:59 CET (67767976233529199 + 1)