Why does AD3AD08 represent a valid date in the .NET framework?

tl;dr: You can use what DateTimeFormatInfo.GetEraName/GetAbbreviatedEraName return as delimiter, ignoring the case. The order is: day, month, year (optional).


It seems you can always use the calendar’s current era’s abbreviated name or full era-name as delimiter for the DateTime tokens. For english cultures it is AD or A.D., e.g. for german cultures it is n. Chr..

var enCulture = new CultureInfo("en-GB");
System.Threading.Thread.CurrentThread.CurrentCulture = enCulture;
var fi = enCulture.DateTimeFormat;
int currentEra = enCulture.Calendar.GetEra(DateTime.Now);
var eraName = fi.GetEraName(currentEra);
var shortEra = fi.GetAbbreviatedEraName(currentEra);
var date = DateTime.Parse($"{shortEra}3{shortEra}08"); // AD or A.D. works

var deCulture = new CultureInfo("de-DE");
System.Threading.Thread.CurrentThread.CurrentCulture = deCulture;
fi = deCulture.DateTimeFormat;
currentEra = deCulture.Calendar.GetEra(DateTime.Now);
eraName = fi.GetEraName(currentEra);
shortEra = fi.GetAbbreviatedEraName(currentEra);
date = DateTime.Parse($"{shortEra}3{shortEra}08");  // n. Chr. works

Interestingly it is case-insensitive, so ad works also. That is documented in DateTimeFormatInfo.GetEra:

The era name is the name a calendar uses to refer to a period of time
reckoned from a fixed point or event. For example, “A.D.” or “C.E.” is
the current era in the Gregorian calendar. The comparison with eraName
is case-insensitive, for example, “A.D.” is equivalent to “a.d.”.

The gregorian calendar has only one era, so Calendar.GetEra(DateTime.Now) isn’t really necessary. I haven’t found any further documentation yet.

Here are some samples that all work and will be parsed to christmas 2017:

DateTime christmas  = DateTime.Parse("ad25ad12ad2017ad");
christmas = DateTime.Parse("AD25ad12ad2017");
christmas = DateTime.Parse("25ad12ad2017AD");
christmas = DateTime.Parse("25ad12ad2017");
christmas = DateTime.Parse("A.D.25ad12ad2017");
christmas = DateTime.Parse("A.D.25ad12ad");  // current year is used
christmas = DateTime.Parse("A.D.25ad12");    // current year is used

Leave a Comment

Hata!: SQLSTATE[HY000] [1045] Access denied for user 'divattrend_liink'@'localhost' (using password: YES)