Search Unity

Question System.DateTime doesn't recognize it's own format?

Discussion in 'Scripting' started by deLord, Aug 14, 2020.

  1. deLord

    deLord

    Joined:
    Oct 11, 2014
    Posts:
    306
    Contrary to the behavior on my laptop, on Android when this line is executed I get the error "FormatException: String was not recognized as a valid DateTime"
    Code (CSharp):
    1. profileCreationDate = System.DateTime.Parse(split[9]);  // "14.08.2020"
    I would understand if I had written the input ("14.08.2020") myself, but this stems from System.DateTime itself.

    Why does DateTime not recognize it's own format?? And why is this behavior different on Android to the behavior on Win7, although the format is the same?
     
  2. Brathnann

    Brathnann

    Joined:
    Aug 12, 2014
    Posts:
    7,187
    https://assetstore.unity.com/packages/tools/integration/log-viewer-12047

    Use log viewer (free) to see your debug messages during runtime. Debug the value after you split it. Debug the character count of the string (finds hidden characters). Debug the string before you split it. Write the string yourself and try to parse it and see if it works.

    Also, you might need cultureInfo maybe to get it to work with .

    You could replace the . with - as well and see if that works.

    https://docs.microsoft.com/en-us/dotnet/standard/base-types/standard-date-and-time-format-strings

    And of course, there is MS doc over DateTime strings.

    Note you could also use tryParse for safety which returns a bool if it fails the parse. But, that's just a safety option.
     
  3. PraetorBlue

    PraetorBlue

    Joined:
    Dec 13, 2012
    Posts:
    7,909
    Most likely a culture/locale difference.
     
  4. deLord

    deLord

    Joined:
    Oct 11, 2014
    Posts:
    306
    I am sitting in front of my laptop (all German settings) in Germany, also my phone is set to German.
    The value split[9] is "14.08.2020" as stated in the comment, I already debugged it on my phone with logcat
     
  5. PraetorBlue

    PraetorBlue

    Joined:
    Dec 13, 2012
    Posts:
    7,909
    Despite your German settings it is possible/plausible that Unity's Mono runtime is not using a German locale. Try printing out
    CultureInfo.CurrentCulture
    and see what it says. In general it's rarely safe to use the variants of DateTime.Parse or Number.Parse etc... that do not explicitly specify a culture.
     
    Suddoha likes this.
  6. deLord

    deLord

    Joined:
    Oct 11, 2014
    Posts:
    306
    Uhm, interestingly, I get an empty string on my phone when I Debug.Log() the CurrentCulture ô.O
    Is this a common phenomenon?
    And how do I fix this??
     
    Last edited: Aug 14, 2020
  7. Antistone

    Antistone

    Joined:
    Feb 22, 2014
    Posts:
    2,836
    DateTime has lots of different ways of being written out as a string. When you call ToString() on a DateTime, you can control what format you get using format specifiers passed as an argument.

    If you want to guarantee that you can get back the original DateTime by parsing the string, then you should use the round-trip format (code "o"). This won't necessarily look very nice if you print it out for a human to read, but if the goal is to save your DateTime into a file and be able to read it back later, then this is what you want.
     
  8. Suddoha

    Suddoha

    Joined:
    Nov 9, 2013
    Posts:
    2,824
    Perhaps that's already Culture.InvariantCulture or anything alike? At least that one prints as an empty string.

    The format you've gotten is not used everywhere. In Germany that's surely one of the most used formats, is it widely spread. Many of the supported cultures, e.g. the invariant culture, and the en-US culture do not expect that though. Instead, among other formats they allow 08.14.2020 (month, day, year).

    You should follow @Antistone's advice and only use actual cultures for display purposes or when you expect user input (then the CurrentCulture is a good guess). If you need to save the values, use one that's not specific to any culture. The InvariantCulture is often used for that.

    This also applies for some other data, like floating point numbers, currency etc.

    It's worth reading a few arcticles and QAs about it, for example this one on StackOverflow (CurrentCulture, InvariantCulture, CurrentUICulture, InstalledUICulture). Sometimes it's a little confusing, but once you heard about it, you can memorize it or quickly find solutions to similar problems. ;)
     
    PraetorBlue likes this.
  9. lordofduct

    lordofduct

    Joined:
    Oct 3, 2011
    Posts:
    8,531
    This!

    And if you really can't change the formatting of it from what you're currently using.

    Then use ParseExact which lets you tell DateTime.Parse what format your string is coming in as:
    https://docs.microsoft.com/en-us/dotnet/api/system.datetime.parseexact?view=netcore-3.1
     
  10. deLord

    deLord

    Joined:
    Oct 11, 2014
    Posts:
    306
    Thanks to your hints I set the format myself and then read it with ParseExact().
    Works now :)