Revision history for DateTime::Format::Genealogy

0.13	Sat Jul 25 17:27:13 EDT 2026
	[ Bug Fixes ]
	- Fix t/error.t failures when Params::Get >= 0.13 croaks before our own usage check
		See https://github.com/nigelhorne/DateTime-Format-Genealogy/issues/11
	- Fix 'return inside eval' bug in _convert_calendar that silently discarded
		Hebrew and French Republican calendar conversions
	- Fix bare clone (->new() on an object) returning the original reference
		instead of a copy
	- Fix ISO date month 00 silently mapping to December via Perl's negative
		array-index wrap; month 13-99 no longer produces undef month name
	- Fix $@ race condition: three eval blocks (validate_strict, Hebrew calendar,
		French Republican calendar) now capture $@ into a lexical immediately so
		a DESTROY firing between the eval and the check cannot silently clear it
	- Fix greedy first-group quantifier in 'bet X and Y' / 'from X to Y' range
		patterns; was picking the last keyword occurrence rather than the first
	- Fix unanchored =~ /FRENCH R/ calendar-type test replaced with string
		equality, preventing false matches on future escape variants
	- Fix 3-digit and oversized years returning today's date instead of undef
		(DateTime::Format::Natural success() was not checked in the GGD-cached path)
	- Fix missing optional calendar module returning a Gregorian DateTime instead
		of undef when DateTime::Calendar::Hebrew or ::FrenchRevolutionary is absent
	- Fix undef canonical field in GGD result crashing DateTime::Format::Natural

	[ Security ]
	- Sanitise user-supplied date strings in all Carp messages via new _safe_str()
		helper: control characters (including CR/LF for log injection, ANSI escapes)
		are replaced with '?' and messages are truncated at 120 characters
	- Add MAX_CACHE_SIZE guard (10,000 entries) in _date_parser_cached to prevent
		memory exhaustion when an adversarial caller feeds unbounded unique strings

	[ Performance ]
	- Cache failed GGD parses as undef in _date_parser_cached; previously only
		successes were memoised, causing repeated O(n) GGD calls for the same
		invalid string and duplicate carp emissions
	- _date_parser_cached now accepts a plain positional arg instead of routing
		through Params::Get, removing measurable dispatch overhead from the hot path
	- _julian_to_gregorian_offset uses a for-loop with early exit instead of grep,
		avoiding temporary list allocation on each Julian date conversion

	[ Enhancements ]
	- Support Object::Configure
	- Use Params::Get in new()
	- Use Params::Validate::Strict to reject unknown parameter keys
	- Use Sub::Private (enforce mode) for _convert_calendar and
		_julian_to_gregorian_offset; use Sub::Protected for _date_parser_cached
	- Use Readonly constants for month alias table, Julian offset tiers, and
		new MAX_CACHE_SIZE limit
	- Consolidate French/German month aliases (Janv, Juli, Mai) into the main
		%MONTH_ALIAS lookup table; remove separate special-case branches
	- quiet and strict flags now fall back to object-level attributes when
		not supplied per-call to parse_datetime
	- Full POD added: EXAMPLE, API SPECIFICATION, MESSAGES, FORMAL SPECIFICATION,
		PSEUDOCODE, and LIMITATIONS sections
	- New t/locales.t covering POSIX locale behaviour
	- New t/unit.t, t/integration.t, t/edge_cases.t, t/extended_tests.t,
		t/function.t — comprehensive black-box, integration, hostile-input,
		coverage-gap, and white-box test suites
	- Eliminate duplicate =head1 SEE ALSO section
	- Minimum Perl version corrected from 5.006_001 to 5.010 (// and //= require it)
	- use Carp () and use Scalar::Util () — explicit non-import; all calls use
		fully-qualified names throughout
	- t/edge_cases.t: timing ceiling raised to 30 s and alarm() subtest skips
		on Windows where alarm() is not implemented

0.12	Wed Aug 13 08:23:37 EDT 2025
	Use Params::Get
	Use Readonly::Values::Months
	Handle DJULIAN, DHEBREW and DFRENCH R in the data 

0.11	Tue Feb 11 14:05:44 EST 2025
	Handle "from xxx to yyy" as well as the more correct "bet xxx and yyy"
	Added _get_params()

0.10	Sat Feb  1 21:01:54 EST 2025
	Use Test::DescribeMe to simplify tests
	refactor _date_parser_cached
	Added t/30-basics.t
	Handle August in French

0.09	Wed Jul 10 08:53:31 EDT 2024
	Fix https://www.cpantesters.org/cpan/report/a12f8d3a-3d93-11ef-8086-6cc8c30391f4

0.08	Sun Jul  7 20:11:22 EDT 2024
	Handle entries with Juli (unless strict is enabled)
	Handle 29-Aug-1938

0.07	Thu Jun 20 07:29:46 EDT 2024
	Handle entries with Janv (unless strict is enabled)

0.06	Tue Apr 23 08:28:40 EDT 2024
	Handle entries which have the French 'Mai' instead of the English 'May'
	Some messages were printed even in quiet mode
	Handle '1517-05-04' as '04/05/1517'

0.05	Thu Mar  2 09:55:57 EST 2023
	Some people use 4 letters for months - handle them
	Allow more formats to be parsed when not strict
	Old dates (say < AD100) used to return today's date, now rejected
	Strings of just a year returned empty string instead of undef

0.04	Sat Apr  3 20:53:13 EDT 2021
	Warn rather than die on unparseable date
	Trap unparsable dates

0.03	Fri Jun 12 20:25:09 EDT 2020
	Added the quiet flag
	Added the strict flag and allow long month names if not given

0.02	Wed Mar  4 10:48:52 EST 2020
	Added check for invalid parameter (thanks to MANWAR)
		See https://github.com/nigelhorne/DateTime-Format-Genealogy/pull/1
	Fix calling in class mode
	Added many more sanity tests
	Be more lenient with callers

0.01	Tue Apr 10 17:30:46 EDT 2018
	First release
