Reputation: 7516
I'm trying to read dates in the following format using a single format string:
"1000.12.31"
"999.12.31"
"99.12.31"
These would correspond to dates in the years 1000 AD, 999 AD and 99 AD.
I've tried the following format strings:
yyyy.M.d
. This fails for the years 999 and 99.
yy.M.d
. This fails for 1000 and 999. It also interprets 99 as 1999.
I'm about to resort to parsing it manually (it's simple enough for that), but i'm curious if something like this is even possible with DateTime.ParseExact
, or perhaps with another built-in method?
Upvotes: 2
Views: 441
Reputation: 21712
It interprets 99 as 1999 because of the current culture's DateTimeFormatInfo
values. If you want to change the parsing behavior you must change the DateTimeFormatInfo
:
string eg = "9.1.2";
DateTime dt;
var fi = new System.Globalization.DateTimeFormatInfo();
fi.Calendar = (System.Globalization.Calendar)fi.Calendar.Clone();
fi.Calendar.TwoDigitYearMax = 99;
fi.ShortDatePattern = "y.M.d";
bool b = DateTime.TryParse(eg, fi, System.Globalization.DateTimeStyles.None, out dt);
New instances of DateTimeFormatInfo
share the same Calendar
object; you have to Clone
it if you want to customize specific instances.
Upvotes: 2
Reputation: 54887
This is trivial to parse manually; I don’t think it’s worth the effort trying to adapt it to work with DateTime.ParseExact
.
string str = "99.12.31";
int[] parts = str.Split('.').Select(int.Parse).ToArray();
DateTime date = new DateTime(parts[0], parts[1], parts[2]);
Upvotes: 2
Reputation: 27864
I think the easiest way would be to take the existing string, stick a few zeros in front of the year, and use your existing DateTime.ParseExact.
However you implement it, I'd go with doing a little manual string massaging, and doing the heavy lifting with DateTime.ParseExact.
static DateTime ParseExactYear(string input)
{
switch (input.IndexOf('.'))
{
case 1: input = "000" + input; break;
case 2: input = "00" + input; break;
case 3: input = "0" + input; break;
}
return DateTime.ParseExact(input, "yyyy.M.d", null);
}
Debug.WriteLine(ParseExactYear("1000.12.31"));
Debug.WriteLine(ParseExactYear("999.12.31"));
Debug.WriteLine(ParseExactYear("99.12.31"));
Debug.WriteLine(ParseExactYear("9.12.31"));
Debug.WriteLine(ParseExactYear("1000.1.1"));
Debug.WriteLine(ParseExactYear("999.1.1"));
Debug.WriteLine(ParseExactYear("99.1.1"));
Debug.WriteLine(ParseExactYear("9.1.1"));
Output:
12/31/1000 12:00:00 AM
12/31/0999 12:00:00 AM
12/31/0099 12:00:00 AM
12/31/0009 12:00:00 AM
1/1/1000 12:00:00 AM
1/1/0999 12:00:00 AM
1/1/0099 12:00:00 AM
1/1/0009 12:00:00 AM
Upvotes: 2