Tez Wingfield
Tez Wingfield

Reputation: 2251

Unable to parse date string using mutliple formats

I'll get straight into it, one of my pet peeves is working with DateTime it's more than likely my lack of understanding when it comes to cultures timezones and globalization.

Within my App, that is used on international level, I'm trying to figure out the best approach to build a function that will handle all formats irrespective of passed in format.

I suppose at the moment I'm not entirely sure, why I have a specific format that will not parse into a date, which is passed in via a client.

This is all in test for the time being, but never the less a pain in the beep...

At the moment, I'm trying to convert en_gb dates and also a standard ISO format Snippet of code attached.

string[] formats = {
    "d/M/yyyy h:mm:ss tt", 
    "d/M/yyyy h:mm tt",
    "dd/MM/yyyy hh:mm:ss", 
    "d/M/yyyy h:mm:ss",
    "d/M/yyyy hh:mm tt", 
    "d/M/yyyy hh tt",
    "d/M/yyyy h:mm",
    "d/M/yyyy h:mm",
    "dd/MM/yyyy hh:mm", 
    "dd/m/yyyy hh:mm",
    "yyyy-MM-dd'T'HH:mm:sszzz",
    "dd/MM/yyyy hh:mm:ss UTC"
};

if (DateTime.TryParseExact(val, formats, 
    CultureInfo.CurrentCulture, 
    DateTimeStyles.AllowWhiteSpaces, out dt))
{
    return dt;
}

So if I may ask, why does 13/06/2017 10:25:00 UTC parse but 27/06/2017 16:11:00 UTC fails (returns false).

I feel I may have been staring at this for too long.

Really appreciate a nudge in the right direction...

Upvotes: 0

Views: 110

Answers (2)

Pramod Sutar
Pramod Sutar

Reputation: 70

Check this out,

static void FormatDate(string strInputDateTimeValue)
        {
            int day = 0, month = 0, year = 0, hours = 0, minutes = 0, seconds = 0, milliSeconds = 0, dateTimeKind = 0;
            List<string> lstSplittedInputDateTime = (from data in strInputDateTimeValue.Split(' ').ToList() where !string.IsNullOrEmpty(data) select data).ToList();
            if (lstSplittedInputDateTime != null)
            {
                string strDate = lstSplittedInputDateTime[0];//Fetching Only Date Part: Considering date format will be mm/DD/yyyy
                if (!string.IsNullOrEmpty(strDate))
                {
                    month = Convert.ToInt32(strDate.Split('/').ToList()[1]);//Fetch Month
                    day = Convert.ToInt32(strDate.Split('/').ToList()[0]);//Fetch Day
                    year = Convert.ToInt32(strDate.Split('/').ToList()[2]);//Fetch Year
                }
                string strTime = lstSplittedInputDateTime[1];//Fetching Only Time Part
                if (strTime != null)
                {
                    hours = Convert.ToInt32(strTime.Split(':').ToList()[0]);//Fetch Hours
                    minutes = Convert.ToInt32(strTime.Split(':').ToList()[1]);//Fetch Minutes
                    seconds = Convert.ToInt32(strTime.Split(':').ToList()[2]);//Fetch Seconds
                    milliSeconds = Convert.ToInt32(strTime.Split(':').ToList()[3]);//Fetch MilliSeconds
                }
                string strDateTimeKind = lstSplittedInputDateTime[2];//Fetching DateTimeKind
                if (strDateTimeKind != null)
                {
                    if (strDateTimeKind.ToLower() == "utc")
                        dateTimeKind = (int)System.DateTimeKind.Utc;
                    else if (strDateTimeKind.ToLower() == "Local")
                        dateTimeKind = (int)System.DateTimeKind.Local;
                    else
                        dateTimeKind = (int)System.DateTimeKind.Utc;
                }
            }
            DateTime dtFormattedDate = new DateTime(year, month, day, hours, minutes, seconds, (DateTimeKind)dateTimeKind);
            Console.WriteLine("Local: {0}", TimeZoneInfo.ConvertTime(dtFormattedDate, TimeZoneInfo.Local).ToString());
            Console.WriteLine("UTC: {0}", TimeZoneInfo.ConvertTime(dtFormattedDate, TimeZoneInfo.Utc).ToString());
        }

        public void Run()
        {
            FormatDate("27/06/2017  16:11:00 UTC");
            Console.ReadLine();
        }

Upvotes: 0

Chris
Chris

Reputation: 27627

Your problem is that you're matching on the time is using h or hh which is 12 hour clock time (ie it accepts 1-12 or 01-12). If you were to add "dd/MM/yyyy HH:mm:ss UTC" to your format list then this would then be able to match 27/06/2017 16:11:00 UTC. In general I suspect anything without the tt specifier probably want to have H/HH rather than h/hh though I leave it to you to decide for sure what you want.

Docs found here: https://learn.microsoft.com/en-us/dotnet/standard/base-types/custom-date-and-time-format-strings#the-h-custom-format-specifier

Upvotes: 1

Related Questions