exupero's blog
RSSApps

Timeline of the patriarchs

In the previous post I created a Gantt chart in which relative events had some uncertainty. In this post we'll switch from a planning situation to a genealogical application, in particular visualizing a timeline of the Hebrew patriarchs as given in the book of Genesis.

While commentators have often used Genesis's genealogies to derive precise dates for biblical events, these genealogies have more ambiguity than is usually recognized. The received text only reports with year resolution, omitting any information about the time of year when births and deaths occurred. A child born when their father is N years old could have been born at their father's Nth birthday or just before their father's (N+1)th birthday. Also, not all cultures count birthdays the same way. In the United States, a child is not one year old until they have lived a full year, while in Korea a child is considered to be one year old the day they are born.

To factor in these uncertainties, we'll adapt the implementation from the previous post. Because the uncertainty is systemic rather than dependent on particular events, we'll leave the uncertainty off events in the schedule and apply them in the absolute-time function:

(defn absolute-time [[entity attribute] events]
  (some (fn [[entity2 attribute2 definition plus-or-minus]]
          (when (= [entity attribute] [entity2 attribute2])
            (if (number? definition)
              (if (zero? definition)
                [0 0]
                [(max 0 (dec definition))
                 (inc definition)])
              (let [[entity3 attribute3 f d] definition
                    f (eval f)
                    [early late] (absolute-time [entity3 attribute3] events)]
                [(max 0 (dec (f early d)))
                 (inc (f late d))]))))
        events))

The ranges can start as much as a year earlier (if using Korean birthday counting), or up to a year later. The exception is the creation of Adam at year zero, which we'll use as a definitive event.

Here's the full list of events, including where in Genesis to find the information:

(def events
  '[[Adam :created 0 "Genesis 5:1-2"]
    [Seth :born [Adam :created + 130] "Genesis 5:3"]
    [Adam :died [Adam :created + 930] "Genesis 5:5"]
    [Enosh :born [Seth :born + 105] "Genesis 5:6"]
    [Seth :died [Seth :born + 912] "Genesis 5:8"]
    [Kenan :born [Enosh :born + 90] "Genesis 5:9"]
    [Enosh :died [Enosh :born + 905] "Genesis 5:11"]
    [Mahalalel :born [Kenan :born + 70] "Genesis 5:12"]
    [Kenan :died [Kenan :born + 910] "Genesis 5:14"]
    [Jared :born [Mahalalel :born + 65] "Genesis 5:15"]
    [Mahalalel :died [Mahalalel :born + 895] "Genesis 5:17"]
    [Enoch :born [Jared :born + 162] "Genesis 5:18"]
    [Jared :died [Jared :born + 962] "Genesis 5:20"]
    [Methuselah :born [Enoch :born + 65] "Genesis 5:21"]
    [Enoch :taken [Enoch :born + 365] "Genesis 5:23"]
    [Lamech :born [Methuselah :born + 187] "Genesis 5:25"]
    [Methuselah :died [Methuselah :born + 969] "Genesis 5:27"]
    [Noah :born [Lamech :born + 182] "Genesis 5:28-29"]
    [Lamech :died [Lamech :born + 777] "Genesis 5:31"]
    [flood :started [Noah :born + 600] "Genesis 7:6"]
    [flood :ended [Noah :born + 601] "Genesis 8:13"]
    [Noah :died [Noah :born + 950] "Genesis 9:29"]
    [Shem :born [Arphaxad :born - 100] "Genesis 11:10"]
    [Arphaxad :born [flood :ended + 2] "Genesis 11:10"]
    [Shem :died [Arphaxad :born + 500] "Genesis 11:11"]
    [Shelah :born [Arphaxad :born + 35] "Genesis 11:12"]
    [Arphaxad :died [Shelah :born + 403] "Genesis 11:13"]
    [Eber :born [Shelah :born + 30] "Genesis 11:14"]
    [Shelah :died [Eber :born + 403] "Genesis 11:15"]
    [Peleg :born [Eber :born + 34] "Genesis 11:16"]
    [Eber :died [Peleg :born + 430] "Genesis 1:17"]
    [Reu :born [Peleg :born + 30] "Genesis 11:18"]
    [Peleg :died [Reu :born + 209] "Genesis 11:19"]
    [Serug :born [Reu :born + 32] "Genesis 11:20"]
    [Reu :died [Serug :born + 207] "Genesis 11:21"]
    [Nahor :born [Serug :born + 30] "Genesis 11:22"]
    [Serug :died [Nahor :born + 200] "Genesis 11:23"]
    [Terah :born [Nahor :born + 29] "Genesis 11:24"]
    [Nahor :died [Terah :born + 119] "Genesis 11:25"]
    [Terah :died [Terah :born + 205] "Genesis 11:32"]
    [Abraham :born [Terah :died - 75] "Genesis 11:32, 12:4"]
    [Isaac :born [Abraham :born + 100] "Genesis 21:5"]
    [Abraham :died [Abraham :born + 175] "Genesis 25:7"]
    [Jacob :born [Isaac :born + 60] "Genesis 25:26"]
    [Isaac :died [Isaac :born + 180] "Genesis 35:28"]
    [Joseph :born [plenty :started - 30] "Genesis 41:46-47"]
    [plenty :started [famine :started - 7] "Genesis 41:53-54"]
    [plenty :ended [plenty :started + 7] "Genesis 41:53-54"]
    [famine :started [Jacob :moved-to-Egypt - 2] "Genesis 45:6"]
    [famine :ended [famine :started + 7] "Genesis 51:53-54"]
    [Jacob :moved-to-Egypt [Jacob :born + 130] "Genesis 47:9"]
    [Jacob :died [Jacob :born + 147] "Genesis 47:28"]
    [Joseph :died [Joseph :born + 110] "Genesis 50:26"]])

From this, we can calculate the earliest and latest year each event could have been:

(map (fn [[entity attribute :as event]]
       [entity attribute (absolute-time event events)])
     events)
([Adam :created [0 0]]
 [Seth :born [129 131]]
 [Adam :died [929 931]]
 [Enosh :born [233 237]]
 [Seth :died [1040 1044]]
 [Kenan :born [322 328]]
 [Enosh :died [1137 1143]]
 [Mahalalel :born [391 399]]
 [Kenan :died [1231 1239]]
 [Jared :born [455 465]]
 [Mahalalel :died [1285 1295]]
 [Enoch :born [616 628]]
 [Jared :died [1416 1428]]
 [Methuselah :born [680 694]]
 [Enoch :taken [980 994]]
 [Lamech :born [866 882]]
 [Methuselah :died [1648 1664]]
 [Noah :born [1047 1065]]
 [Lamech :died [1642 1660]]
 [flood :started [1646 1666]]
 [flood :ended [1647 1667]]
 [Noah :died [1996 2016]]
 [Shem :born [1547 1571]]
 [Arphaxad :born [1648 1670]]
 [Shem :died [2147 2171]]
 [Shelah :born [1682 1706]]
 [Arphaxad :died [2084 2110]]
 [Eber :born [1711 1737]]
 [Shelah :died [2113 2141]]
 [Peleg :born [1744 1772]]
 [Eber :died [2173 2203]]
 [Reu :born [1773 1803]]
 [Peleg :died [1981 2013]]
 [Serug :born [1804 1836]]
 [Reu :died [2010 2044]]
 [Nahor :born [1833 1867]]
 [Serug :died [2032 2068]]
 [Terah :born [1861 1897]]
 [Nahor :died [1979 2017]]
 [Terah :died [2065 2103]]
 [Abraham :born [1989 2029]]
 [Isaac :born [2088 2130]]
 [Abraham :died [2163 2205]]
 [Jacob :born [2147 2191]]
 [Isaac :died [2267 2311]]
 [Joseph :born [2234 2286]]
 [plenty :started [2265 2315]]
 [plenty :ended [2271 2323]]
 [famine :started [2273 2321]]
 [famine :ended [2279 2329]]
 [Jacob :moved-to-Egypt [2276 2322]]
 [Jacob :died [2293 2339]]
 [Joseph :died [2343 2397]])

While there's only a range of a few years when Seth could have been born, every generation adds to the margin of uncertainty, until by the end of Genesis, the timing of Joseph's death has more than 50 years of wiggle room. That's not so long over several millennia, but it is much larger than you'll see on a typical timeline of Bible events.

To visualize this, let's restructure the data to group it by entity:

(def data
  (->> events
    (map (fn [[entity attribute :as event]]
           [entity attribute (absolute-time event events)]))
    (group-by first)
    (map (fn [[entity events]]
           [entity (into {} (map #(vec (drop 1 %))) events)]))
    (sort-by #(apply min (flatten (vals (second %)))))))
([Adam {:created [0 0], :died [929 931]}]
 [Seth {:born [129 131], :died [1040 1044]}]
 [Enosh {:born [233 237], :died [1137 1143]}]
 [Kenan {:born [322 328], :died [1231 1239]}]
 [Mahalalel {:born [391 399], :died [1285 1295]}]
 [Jared {:born [455 465], :died [1416 1428]}]
 [Enoch {:born [616 628], :taken [980 994]}]
 [Methuselah {:born [680 694], :died [1648 1664]}]
 [Lamech {:born [866 882], :died [1642 1660]}]
 [Noah {:born [1047 1065], :died [1996 2016]}]
 [Shem {:born [1547 1571], :died [2147 2171]}]
 [flood {:started [1646 1666], :ended [1647 1667]}]
 [Arphaxad {:born [1648 1670], :died [2084 2110]}]
 [Shelah {:born [1682 1706], :died [2113 2141]}]
 [Eber {:born [1711 1737], :died [2173 2203]}]
 [Peleg {:born [1744 1772], :died [1981 2013]}]
 [Reu {:born [1773 1803], :died [2010 2044]}]
 [Serug {:born [1804 1836], :died [2032 2068]}]
 [Nahor {:born [1833 1867], :died [1979 2017]}]
 [Terah {:born [1861 1897], :died [2065 2103]}]
 [Abraham {:born [1989 2029], :died [2163 2205]}]
 [Isaac {:born [2088 2130], :died [2267 2311]}]
 [Jacob
  {:born [2147 2191], :moved-to-Egypt [2276 2322], :died [2293 2339]}]
 [Joseph {:born [2234 2286], :died [2343 2397]}]
 [plenty {:started [2265 2315], :ended [2271 2323]}]
 [famine {:started [2273 2321], :ended [2279 2329]}])

Here's the full timeline, in which the light-colored areas represent the earliest a character could have been born and the latest they could have died, or in the case of events like Noah's flood or Joseph's famine, the earliest an event could have started and the latest it could have ended. The dark rectangles delimit the latest a character could have been born and the earliest they could have died.

2002004004006006008008001,0001,0001,2001,2001,4001,4001,6001,6001,8001,8002,0002,0002,2002,200AdamSethEnoshKenanMahalalelJaredEnochMethuselahLamechNoahShemfloodfloodArphaxadShelahEberPelegReuSerugNahorTerahAbrahamIsaacJacobJosephJosephplentyplentyfaminefamine

In theory we could halve the range of possibilities if we knew which year-counting system the original author was using (western or Korean), but it's also possible that the final text relied on multiple sources that used different year-counting strategies, as the later books of Kings and Chronicles seem to do when documenting the reigns of various monarchs.