A 3-bytes data type for historical and general purpose date modeling:
|Fuzzy Date||How to Input|
|August 212 BC||
|August 6, 212 BC||
|? 24 BC||
|? c. 20 BC||
|10s BC - 0s BC||
|10s BC - 0s AD||
|0s BC - 0s AD||
|c. 9 BC - 7 BC||
|c. 9 BC - 12 AD||
|1 BC - 1 AD||
|2010s - 2020s||
|January 1, 2014||
|2014 - 2015||
The Long Version
Most data types dealing with date are designed to represent a certain date with varying ranges (usually starts from 1, 1753, 1900, or 1970) and accuracies (usually from 100 nanoseconds to 1 day).
Below examples are common seen in historical and general purpose writings:
- 2014 (year only)
- January 2014 (year and month only)
- 252 BC (before Christ)
- 1950s (one decade)
- 1966 - 1976 (spanning 10 years)
- circa 1791 (around a certain year)
- ? January 16, 1078 (uncertain date)
None of above can be stored or processed using existing data types. We do not
String as an option since it's:
- storage inefficient
- hard to sort
- hard to localize
Fuzzy Date proposes:
- a 3-byte data type flexible in modeling date
- a set of functions dealing with above format
The binary format aims to be:
- storage efficient
3 bytes are used to store a fuzzy date:
[8Y] [4Y][4M] [5D][A][B][C]
- 12 Year Bits:
The 1st byte and top 4 bits of the 2nd byte are year bits. Total space of:
2 ^ 12 = 4096
The mapping between 12 year bits and the actual year is:
0b000000000000represents a fuzzy date without a year part, e.g.:
- February (month only)
- February 1 (month and day only)
- February 29 (all possible days of a month)
substract 1024 for all other combos, we get a year within:
- 1024 BC (
0b000000000001- 1024 = -1023) and
- 3071 AD (
0b111111111111- 1024 = 3071)
- 1024 BC (
4 Month Bits:
0b0000represents a decade (day bits should be
0b00000) or a fuzzy date spanning multi-decades, e.g.:
- 1860s - 1870s
For BC decades, the year is the start year of the decades, e.g.:
- The year bits for 10s BC are same as 19 BC (-18).
0b0001represents a fuzzy date with only a year part (day bits should be
0b1110is reserved which should not be used in the current spec version.
0b1111represents a fuzzy date spanning multiple years, e.g.:
- 1791+2 (day bits denote year span, from 1 to 32)
substract 1 for all other combos, we get a month within:
- 1 (
0b0010- 1) and
- 12 (
- 1 (
5 Day Bits:
When month bits are
0b1111, day bits denote year span, otherwise:
0b00000represents a fuzzy date without a day part, e.g.:
- January 1791
0b11111represents day 1 to day 31 accordingly.
Flag Bit A: Certainty.
1: the date is certain
0: the date is uncertain, e.g.:
- ? 1791
- ? January 1791
Flag Bit B: Accuracy.
1: the date is accurate
0: the date is approximate, e.g.:
- circa 1791
- circa January 1791
Flag Bit C: Special flag. ICMD use flag bit C to denote
1: the fuzzy date is not a floruit date
0: the fuzzy date is not a floruit date, e.g.:
- fl. 1234
An application can define its own usage for flag bit C. Keep it
1 when you
don't need it.
Uncertain/approximate dates go before certain/accurate dates in
ascending order (default for print). Thus, all flag bits are
1 by default.
is_valid_binary: Check if a binary is a valid fuzzy date binary.
binary_from_string: Parse a short string into a fuzzy date binary.
string_from_binary: Parse a fuzzy date binary into a short string.
readable_string_from_binary: Parse a fuzzy date binary into a readable (en-us) string.
string_from_binary are mutually inverse functions.
year_of: Return the year part of a fuzzy date,
month_of: Return the month part of a fuzzy date,
day_of: Return the day part of a fuzzy date,
year_diff: Return the difference in years between two fuzzy dates,
fuzzy_date_2_markup: Return markuped date (for navigation use):
fuzzy_date_2_julian_markup: Return markuped Julian date (for navigation use).
- 1 BC before 1 AD, no 0 AD.
- Year span 1 to 32, not 0 to 31.