Skip to content

Fuzzy date — uncertain chronological dating ​

The fuzzy-date plugin adds a structured chronology section to any table. It stores uncertain, approximate, or range-based dates in five dedicated columns directly in the core table — making them searchable, filterable, and usable by other plugins such as the GeoFace temporal filter and the Harris Matrix absolute timeline.

When to use it ​

Use this plugin when your records have a dating that is:

  • Approximate — "probably 4th century BC"
  • A range — "between 350 and 300 BCE"
  • One-sided — "not later than 300 BCE" (ante quem) or "not earlier than the late 4th century BCE" (post quem)
  • Uncertain — "possibly Hellenistic"

Enabling the plugin for a table ​

Go to Config → Tables, select the table, scroll to the System plugins section and toggle Chronology (fuzzy date) on. The system immediately adds five columns to the table and confirms with a toast message. No other configuration is required.

To disable, toggle the switch off. The columns — and any data already entered — are preserved; the panel simply disappears from RecordView. Toggle it back on at any time to restore the panel without data loss.

The chronology panel ​

Once enabled, a Chronology section appears in RecordView below the regular fields.

Read mode ​

Displays the stored chronology as a formatted label (derived from the chronology string, or from chrono_from / chrono_to), a certainty badge, and an optional period name. Examples:

Late 4th cent. BCE Probable · Hellenistic

Ante quem: 4th cent. BCE Uncertain

350 BCE – 300 BCE Certain

Edit mode ​

The panel shows three inputs:

InputPurpose
Chronology stringPrimary input — see grammar below
CertaintyCertain / Probable / Uncertain
PeriodFree text or vocabulary term (qualitative label only)

There is no separate label field — the chronology string is the label. Typing in it triggers live parsing, and a preview shows the generated label and the numeric range (from – to) so you can verify the result before saving.

Chronology string grammar ​

The chronology string is the primary input method. It supports two token types: century and year. The general structure is:

input = token             → single date or century range
      | token / token     → explicit range
      | ? / token         → ante quem
      | token / ?         → post quem
      | ?                 → undated

Century tokens ​

A century token starts with c (mandatory), followed by the century number, an optional qualifier, and the era:

c{N}{qualifier} {BCE|CE}
QualifierMeaningExampleRange
(none)Full centuryc4 BCE400–301 BCE
eEarly (~first 25%)c4e BCE400–376 BCE
mMid (~middle 50%)c4m BCE375–326 BCE
lLate (~last 25%)c4l BCE325–301 BCE
h1First halfc4h1 BCE400–351 BCE
h2Second halfc4h2 BCE350–301 BCE
q1 – q4Quarter 1–4c4q3 BCE350–326 BCE

Year tokens ​

FormatExampleMeaning
-N-350Year 350 BCE
N BCE350 BCEYear 350 BCE
N or N CE300 or 300 CEYear 300 CE

Disambiguation

4 BCE means year 4 BCE (not the 4th century). To express the 4th century BCE, write c4 BCE. The c prefix is what identifies a century token.

Range and one-sided dates ​

InputMeaningStored as
c4l BCE / c3m CELate 4th BCE to mid 3rd CEfrom=–325, to=275
-350 / -300Years 350–300 BCEfrom=–350, to=–300
? / c4q3 BCEAnte quem: before 3rd quarter 4th BCEfrom=null, to=–326
c4l BCE / ?Post quem: after late 4th BCEfrom=–325, to=null
?Undatedfrom=null, to=null

Data model ​

Five columns are added to the core table when the plugin is activated:

ColumnTypeMeaning
chrono_fromINTEGERStart year (negative = BCE). NULL for ante quem or undated.
chrono_toINTEGEREnd year. NULL for post quem or undated.
chrono_labelVARCHAR(200)The chronology string as typed (e.g. c4l BCE / c3m CE, -50/200, ?). The displayed label is computed from it — this is not a free-text field.
chrono_certaintyINTEGER1 = certain · 2 = probable · 3 = uncertain. Legacy string values (certain / probable / possible) from older databases are still read.
chrono_periodVARCHAR(200)Qualitative period name (e.g. "Hellenistic"). No numeric mapping.

The dating type is implicit — no separate type column is needed:

chrono_fromchrono_toType
nullnullUndated
XXPoint date (exact year)
XY (X < Y)Range / circa
nullYAnte quem
XnullPost quem

Searching by chronology ​

_chrono_overlap — the primary operator ​

Use _chrono_overlap on chrono_from to find all records whose dating intersects a given range. It correctly handles the NULL semantics of ante quem and post quem records:

filter[chrono_from][_chrono_overlap][]=-400&filter[chrono_from][_chrono_overlap][]=-300

Or as a JSON body:

json
{ "chrono_from": { "_chrono_overlap": [-400, -300] } }

The operator generates a three-branch condition:

Record typeIncluded if
Normal range (from and to set)range overlaps [low, high]
Ante quem (from is null)to >= low
Post quem (to is null)from <= high
Undated (both null)never

WARNING

Use _chrono_overlap on chrono_from only. Applying it to any other field returns an error.

Filtering by other chrono fields ​

The remaining chrono columns support all standard operators:

# Records with probable certainty (1 = certain, 2 = probable, 3 = uncertain)
filter[chrono_certainty][_eq]=2

# Records in the Hellenistic period
filter[chrono_period][_icontains]=hellenistic

# Records with a label containing "BCE"
filter[chrono_label][_icontains]=BCE

# Records that have any chrono data (not undated)
filter[chrono_to][_nnull]=true

Integration with other plugins ​

PluginIntegration
GeoFaceWhen the fuzzy-date plugin is active on a table, GeofaceView shows a Temporal filter bar with a dual-handle year slider (range −3000 to 2000, step 25 years). Dragging the handles filters map markers in real time using _chrono_overlap, correctly including ante quem and post quem records that intersect the selected window.
Harris MatrixA Chronological toggle in the Matrix toolbar positions stratigraphic units on a vertical year axis using their chrono_from / chrono_to, keeping the stratigraphic columns so topology and calendar time are visible together. See Absolute chronological timeline.