Cannot convert string to DateTime in uwp

2019-09-10 12:30发布

问题:

private string GetSystem()
{
    StringBuilder results = new StringBuilder();

    DateTimeFormatter[] basicFormatters = new[]
    {
        // Default date formatters
        new DateTimeFormatter("shortdate"),

        // Default time formatters
        new DateTimeFormatter("longtime"),
    };

    DateTime dateandTime = DateTime.Now;

    foreach (DateTimeFormatter formatter in basicFormatters)
    {
        // Format and display date/time.
        results.Append(formatter.Format(dateandTime));
        results.Append(" ");
    }           
    return results.ToString();
}

dateString = GetSystem();
format = "dd-MM-yyyy HH:mm:ss";
provider = new CultureInfo("en-IN");
try
{           
    result = DateTime.ParseExact(dateString, format, System.Globalization.CultureInfo.InvariantCulture);
    Debug.WriteLine("{0} converts to {1}.", dateString, result.ToString());
}
catch (FormatException)
{
    Debug.WriteLine("{0} is not in the correct format.", dateString);
}

I'm getting the error

"String was not recognized as a valid DateTime"

while running this code can anyone suggest some idea to resolve my problem.

回答1:

In UWP apps, while using Format Template like shortdate or longtime, by default it will use user's default global context which are shown in Settings under Time & Language. And in my computer, they are set as following:
So when I use your GetSystem method in my side, the dateString is like

6‎/‎1‎/‎2016 ‎1:‎44‎:‎43‎ ‎PM

and obviously this can't be parsed with format = "dd-MM-yyyy HH:mm:ss";. So I think using a fixed custom date and time format string here is not a good practice.

Then even when the format of your dateString matches the format you've used in DateTime.ParseExact method, you will also get the error: String was not recognized as a valid DateTime.

This is because, when we use DateTimeFormatter.Format method, there are some invisible 8206 characters in its return value. So your dateString looks like 30‎-‎05‎-‎2016 ‎14‎:‎54‎:‎18, but actually it's not 30-05-2016 14:54:18. To see this clearly, we can convert the dateString to char array. Here using "shortdate" template for example:

var dateString = new DateTimeFormatter("shortdate").Format(DateTime.Now);
var array = dateString.ToCharArray();
foreach (var item in arry)
{
    Debug.WriteLine(item);
}

And the char array will like:

So to solve your problem, I'd suggest you use The General Date Long Time ("G") Format Specifier.

The "G" standard format specifier represents a combination of the short date ("d") and long time ("T") patterns, separated by a space.

You can use this format specifier like following:

var dateString = DateTime.Now.ToString("G");

And then convert string to DateTime like:

var result = DateTime.Parse(dateString);

Or

var result = DateTime.ParseExact(dateString, "G", null);

the provider here is null which represents the CultureInfo object that corresponds to the current culture is used. If we use wrong culture here, we will also get String was not recognized as a valid DateTime exception.

If you do want to use dd-MM-yyyy HH:mm:ss format, you can use some code like:

var dateString = DateTime.Now.ToString("dd-MM-yyyy HH:mm:ss");

And the convert is as same as above, only in this scenario the provider parameter is not important.