Forcing DateTime.Parse to Fail for Invariant Dates

1k views Asked by At

I'll be brief to start, then give details at the end. Consider the following code:

CultureInfo cultureToTest = new CultureInfo("hu-HU");
Thread.CurrentThread.CurrentCulture = cultureToTest;
DateTime testDateTime = new DateTime(2014,12,13,23,24,25);
String testString = testDateTime.ToString(CultureInfo.InvariantCulture);
DateTime actualDateTime = DateTime.Parse(testString);

The question is whether there is any possible value of cultureToTest which would either cause the DateTime.Parse call to throw an exception or to return the wrong value?


Context:

This is for a set of unit tests. There is a body of code which calls DateTime.Parse without specifying the culture. My concern was that when this code is passed a date in the Invariant or en-US cultures, that the code could fail in some cultures. My proposed solution was to change that code to use

DateTime.Parse(string, CultureInfo.InvariantCulture)

in these cases.

In order to unit test the change, I need to call the new code with a culture that would have made the original DateTime.Parse(string) fail, then to show that the changed code will succeed.

The problem is that I haven't yet found a culture that will do this for me. I'm going to try to manufacture one, but thought I'd ask the more general question first.

2

There are 2 answers

2
John Koerner On BEST ANSWER

Using this code:

StringBuilder sb = new StringBuilder();
foreach (var culture in CultureInfo.GetCultures(CultureTypes.AllCultures))
{
    try
    {
        Thread.CurrentThread.CurrentCulture = culture;
        DateTime testDateTime = new DateTime(2014, 12, 13, 23, 24, 25);
        String testString = testDateTime.ToString(CultureInfo.InvariantCulture);
        DateTime actualDateTime = DateTime.Parse(testString);
        Console.WriteLine(actualDateTime.Day.ToString());
    }
    catch (Exception ex)
    {
       sb.AppendLine(culture.ToString());
    }
}

Console.WriteLine(sb.ToString());

The following cultures throw an exception when parsing that date:

am
am-ET
ar
ar-AE
ar-BH
ar-DZ
ar-EG
ar-IQ
ar-JO
ar-KW
ar-LB
ar-LY
ar-MA
ar-OM
ar-QA
ar-SA
ar-SY
ar-TN
ar-YE
arn
arn-CL
as
as-IN
az
az-Cyrl
az-Cyrl-AZ
az-Latn
az-Latn-AZ
ba
ba-RU
be
be-BY
bg
bg-BG
bn
bn-BD
bn-IN
br
br-FR
bs
bs-Cyrl
bs-Cyrl-BA
bs-Latn
bs-Latn-BA
ca
ca-ES
ca-ES-valencia
co
co-FR
cs
cs-CZ
cy
cy-GB
da
da-DK
de
de-AT
de-CH
de-DE
de-LI
de-LU
dsb
dsb-DE
dv
dv-MV
el
el-GR
en-029
en-AU
en-BZ
en-GB
en-HK
en-IE
en-IN
en-JM
en-MY
en-NZ
en-SG
en-TT
en-ZW
es
es-419
es-AR
es-BO
es-CL
es-CO
es-CR
es-DO
es-EC
es-ES
es-GT
es-HN
es-MX
es-NI
es-PA
es-PE
es-PR
es-PY
es-SV
es-UY
es-VE
et
et-EE
fa
fa-IR
ff
ff-Latn
ff-Latn-SN
fi
fi-FI
fo
fo-FO
fr
fr-BE
fr-CD
fr-CH
fr-CI
fr-CM
fr-FR
fr-HT
fr-LU
fr-MA
fr-MC
fr-ML
fr-RE
fr-SN
fy
fy-NL
ga
ga-IE
gd
gd-GB
gl
gl-ES
gn
gn-PY
gsw
gsw-FR
gu
gu-IN
ha
ha-Latn
ha-Latn-NG
he
he-IL
hi
hi-IN
hr
hr-BA
hr-HR
hsb
hsb-DE
hy
hy-AM
id
id-ID
ig
ig-NG
is
is-IS
it
it-CH
it-IT
iu
iu-Cans
iu-Cans-CA
iu-Latn
iu-Latn-CA
jv
jv-Latn
jv-Latn-ID
ka
ka-GE
kk
kk-KZ
kl
kl-GL
km
km-KH
kn
kn-IN
kok
kok-IN
ky
ky-KG
lb
lb-LU
lo
lo-LA
lv
lv-LV
mg
mg-MG
mi
mi-NZ
mk
mk-MK
ml
ml-IN
mr
mr-IN
ms
ms-BN
ms-MY
mt
mt-MT
my
my-MM
nb
nb-NO
nl
nl-BE
nl-NL
nn
nn-NO
no
nqo
nqo-GN
nso
nso-ZA
oc
oc-FR
om
om-ET
or
or-IN
pa
pa-Arab
pa-Arab-PK
pa-IN
pt
pt-AO
pt-BR
pt-PT
qut
qut-GT
quz
quz-BO
quz-EC
quz-PE
rm
rm-CH
ro
ro-MD
ro-RO
ru
ru-RU
rw
rw-RW
sa
sa-IN
sah
sah-RU
sd
sd-Arab
sd-Arab-PK
se
se-FI
se-NO
sk
sk-SK
sl
sl-SI
sma-NO
smj-NO
smn
smn-FI
sms
sms-FI
sn
sn-Latn
sn-Latn-ZW
so
so-SO
sq
sq-AL
sr
sr-Cyrl
sr-Cyrl-BA
sr-Cyrl-CS
sr-Cyrl-ME
sr-Cyrl-RS
sr-Latn
sr-Latn-BA
sr-Latn-CS
sr-Latn-ME
sr-Latn-RS
sv-FI
syr
syr-SY
ta
ta-IN
ta-LK
te
te-IN
tg
tg-Cyrl
tg-Cyrl-TJ
th
th-TH
ti
ti-ER
ti-ET
tk
tk-TM
tn
tn-BW
tn-ZA
tr
tr-TR
tt
tt-RU
tzm
tzm-Latn
tzm-Latn-DZ
tzm-Tfng
tzm-Tfng-MA
uk
uk-UA
ur
ur-IN
ur-PK
uz
uz-Cyrl
uz-Cyrl-UZ
uz-Latn
uz-Latn-UZ
vi
vi-VN
wo
wo-SN
yo
yo-NG
zgh
zgh-Tfng
zgh-Tfng-MA
zh-Hant
zh-HK
zh-MO
zh-SG
zu
zu-ZA
zh-CHT
1
MarcinJuraszek On

It throws an exception for en-GB.

That's because invariant culture data format is set to MM/dd/yyyy. For en-GB it's dd/MM/yyyy, which means you're trying to parse date with month set to 13, which is incorrect.

For dates where day is lower than 13, input string will be parsed without exception, but result will be incorrect (unless day and month are the same number).