11

I don't understand Why there is an overload with IFormatProvider in DateTime.ParseExact ?

If I'm defining exactly how it should be parsed ( spaces , separators etc) , then theres should be no problem :

All these 3 examples show the same result:

example 1

CultureInfo provider =CultureInfo.CreateSpecificCulture("en-US");
var t=  DateTime.ParseExact("13-2-2013", "d-M-yyyy", provider, DateTimeStyles.None);  
Console.WriteLine (t); //13/02/2013 00:00:00

example 2

  CultureInfo provider =CultureInfo.CreateSpecificCulture("en-US");
  var t=    DateTime.ParseExact("13/2/2013", "d/M/yyyy", provider, DateTimeStyles.None);  
  Console.WriteLine (t); //13/02/2013 00:00:00

example 3

 CultureInfo provider =CultureInfo.CreateSpecificCulture("en-US");
var t=  DateTime.ParseExact("13@@@2@@@2013", "d@@@M@@@yyyy", provider, DateTimeStyles.None);  
 Console.WriteLine (t); //13/02/2013 00:00:00

So why do i need to provide provider If I'm explicitly defining the structure ?

leppie
  • 115,091
  • 17
  • 196
  • 297
Royi Namir
  • 144,742
  • 138
  • 468
  • 792

3 Answers3

9

There are still format specifiers that are culture dependant, like the time separator (:) and the date separator (/). Those doesn't match a specific character, but the separator specified in the culture.

Bridge
  • 29,818
  • 9
  • 60
  • 82
Guffa
  • 687,336
  • 108
  • 737
  • 1,005
  • but I'm specifying what are those seperators ! (sample : @@@) – Royi Namir Feb 13 '13 at 10:04
  • @Royi, not really. You would have to enclose `/` characters in single quotes to achieve that. Your second example currently parses the date with your culture's date separator. – Frédéric Hamidi Feb 13 '13 at 10:05
  • @RoyiNamir: If you use `-`, then that's a literal character, but if you use `/`, then it's the date separator specifier, and that is different characters depending on the culture. Using a swedish cutlure for example, the date separator is the `-` character. – Guffa Feb 13 '13 at 10:06
  • Guffa , But then I will write `d-M-yyyy`. I dont understand – Royi Namir Feb 13 '13 at 10:07
  • @RoyiNamir: Using the format `d/M/yyyy` and a swedish culture would match a date like `13-2-2013`. – Guffa Feb 13 '13 at 10:08
  • so `/` is .net universal and is read differently depending on the provider ? – Royi Namir Feb 13 '13 at 10:10
  • @Royi It depends on the separator character defined in the OS settings for the current culture. – John Willemse Feb 13 '13 at 10:13
  • @Guffa So can you explain why `d-M-yyyy` also work ? `-` is not a date seperator. – Royi Namir Feb 13 '13 at 10:41
  • @RoyiNamir: The format `d-M-yyyy` will match a date like `13-2-2013` regardless of the culture setting, i.e. it won't match a date like `13/2/2013` even if you specify an en-US culture. The dash doesn't have a special meaning in a date format, so it's just a literal character, just as when you used `@@@` as separator. – Guffa Feb 13 '13 at 10:47
  • (don't get mad :-)) but - So - When should I use `-` ? only when it's a custom made seperator like `@@@` ? – Royi Namir Feb 13 '13 at 11:05
  • @RoyiNamir: You would use `-` when you want it to be that specific character regardless of the culture. – Guffa Feb 13 '13 at 12:13
  • @Guffa But If i know **exactly** what I am expecting (by provider) so why do i need the `/` ? i could use `.` I opened a bounty for this question. – Royi Namir Feb 17 '13 at 08:47
  • @RoyiNamir: If you know exactly what to expect, you can use a format string without culture dependant format specifiers. Then you don't need to specify the culture. The culture independant format string for a date like `13/2/2013` would be using apostrophes: `"d'/'M'/'yyyy"`, or the \ escape character: `"d\\/M\\/yyyy"`. – Guffa Feb 17 '13 at 09:12
  • 1
    @Guffa You say _If you know exactly what to expect,_ but Mustn't I know exactly ? I mean If you build a web page and you put a textbox with a datepicker , would you tell the datepicker to use `mm/dd/yyyy` format for the whole world ? cause if so , you will know exactly what to parse.but what if you don't tell the datepicker the foramt ? then a user might enter his own format. and now we have a problem.... ( or does your answer is based on the fact that I should check the userAgent culture and then do `new CultureInfo(GetFromUserAgent())`...Thanks Guffa. – Royi Namir Feb 17 '13 at 12:41
  • @RoyiNamir: The reply was based on the question where you stated that you know exacty what to expect, so it naturally doesn't answer anything about when you don't know what to expect. If you want to allow the user to use their own native format, then you can either use the culture from the agent, or give the `ParseExact` an array of different possible formats to choose from. – Guffa Feb 17 '13 at 13:14
  • @Guffa 2 questions please : **1)** I can't test it but if you open now a web date-picker in sweden , do you see a date separator as `[.]` ? is it dependent on the local browser settings ? **2)** So you are basically telling me that if I build a site (world wide use ( like SO)) and it has a date-picker, so I _won't_ be able to use parseExact cause every browser will send its own date format....is that correct ? (unless i'm setting fixed format to the datepicker...) am I correct? – Royi Namir Feb 18 '13 at 07:42
  • @Guffa can you please answer my last comment ? – Royi Namir Feb 18 '13 at 16:11
  • @RoyiNamir: 1. That depends on what the date-picker uses, and the settings in the browser. The swedish date separator is `-`, but the default date format in Javacript doesn't use a separator like that, and it even varies between browsers. In Firefox I get the default date format `Mon Feb 18 2013 17:14:47 GMT+0100`. IE on the other hand gives me `Mon Feb 18 17:21:09 UTC+0100 2013`. – Guffa Feb 18 '13 at 16:24
  • 2. Yes, if you have a numeric date format depending on the client culture you would need to know the culture to parse it. The date `1/2/2013` could be either `Jan 2 2013` or `Feb 1 2013`. Even for the same culture you will get different formats for different browsers, so it would be hard to set up `ParseExact` to handle all of them. – Guffa Feb 18 '13 at 16:25
  • Thank you Guffa and sorry for all those questions :-) – Royi Namir Feb 26 '13 at 07:47
1

Because:

  1. The specified format can include localized names of weekdays and months.
  2. The characters : and / in the format string do not represent literal characters but rather the separator as specified by the format provider (see the bottom of the table here).
Jon
  • 428,835
  • 81
  • 738
  • 806
  • so for my example which is pure date - it isn't needed...right ? – Royi Namir Feb 13 '13 at 10:04
  • @RoyiNamir: No, the forward slash also represents a culture-specific delimiter. You 'd need `'/'` to specify a literal slash. – Jon Feb 13 '13 at 10:06
  • can you supply example which will break my sample ? – Royi Namir Feb 13 '13 at 10:08
  • @RoyiNamir: Change the culture from `en-US` to `de` and try example #2; it breaks. Do the same in example #1 and it still works. That's because `/` is treated specially and `-` is not. – Jon Feb 13 '13 at 10:09
  • Jon , so if I'm specifying `CultureInfo.CreateSpecificCulture("de");` - that requires me to use the appropriate seperators in the format pattern? – Royi Namir Feb 13 '13 at 10:19
  • 1
    @RoyiNamir: No. Whenever you use `/` or `:` in the format string, the input string needs to have the corresponding separators from the format provider at those places. If the format provider uses `/` and `:` as the separators (as in `en-US`) then this is not apparent. But for a provider like the `de` culture, whenever you specify `/` in the format you need `-` in the input. – Jon Feb 13 '13 at 10:22
  • `CultureInfo provider =CultureInfo.CreateSpecificCulture("de"); var t= DateTime.ParseExact("13-2-2013", "d/M/yyyy", provider, DateTimeStyles.None);` According to your last comment this should work ( also can u please go to chat ? ) - – Royi Namir Feb 13 '13 at 10:24
  • @RoyiNamir: Sorry, my mistake -- the separator for the `de` culture is the dot. So `"13.2.2013", "d/M/yyyy"` would work. – Jon Feb 13 '13 at 10:44
  • so why would I ever need to specify literal separators ? just for custom mode like my @@@ sample ? – Royi Namir Feb 13 '13 at 11:28
  • @RoyiNamir: You 'd want to specify literals in all cases where you expect the input to be in a culture-agnostic format. – Jon Feb 13 '13 at 11:34
  • So I have to know "is the date string im gonna parse is in (any) official format" ? - if it is i will use `/` else i will use the `@@@`...(...)? – Royi Namir Feb 13 '13 at 11:47
1

I can mainly imagine a web application and maybe a form, where the client submits informations to the server. This form also contains a datepicker, and sends the selected date based on the specific culture. So if the website used in the USA, they send 13/2/2013, while from Germany you get 13.2.2013. So how you handle the date in your server side code?

You could use sometheing like this in ASP.NET MVC (thanks to Sergey, Get CultureInfo from current visitor and setting resources based on that?):

var userLanguages = Request.UserLanguages;
CultureInfo ci;
if (userLanguages.Count > 0)
{
    try
    {
        ci = new CultureInfo(userlanguages[0]);
    }
    catch(CultureNotFoundException)
    {
         ci = CultureInfo.InvariantCulture;
    }
}
else
{
    ci = CultureInfo.InvariantCulture;
}

And then parse to datetime:

var t = DateTime.ParseExact(formDateString, "d/M/yyyy", ci, DateTimeStyles.None);  
Community
  • 1
  • 1
tungi52
  • 632
  • 1
  • 8
  • 15
  • and what if the user enters `2/13/2013` ? I would have to change the pattern from `"d/M/yyyy"` to `M/d/yyyy` thats my problem.**does parse exact is only for situations where I know exactly the M||d||yyyy locations?** – Royi Namir Feb 17 '13 at 08:29
  • No, because you don't create a simple textbox, however a datepicker, where the users can select the date interactively, and the control shows the selected date based on the user's culture. Then on a button click you make a request to the server, where you sends the date as a simple string. And yes, in ParseExact you should explicitly tell the format, insted of Parse, which is a more flexible way to convert string to datetime. – tungi52 Feb 17 '13 at 08:53
  • But if the datepicker always show with `/` ( cause I told it in JS) ? why would i need to declare a culture ? – Royi Namir Feb 17 '13 at 10:47