Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Parsing the DateTime format to get Format String

I would like to be able to get the format string from a DateTime string.

e.g.

"2012-12-08 15:00:00" => "yyyy-MM-dd HH:mm:ss"

"2013/30/01 16:00" => "yyyy/dd/MM HH:mm"

Is this possible?

like image 623
ronag Avatar asked Sep 19 '13 10:09

ronag


People also ask

How do I convert a DateTime to a string?

We can convert a string to datetime using strptime() function. This function is available in datetime and time modules to parse a string to datetime and time objects respectively.

What is parsing how do you parse a date time string?

The Parse method tries to convert the string representation of a date and time value to its DateTime equivalent. It tries to parse the input string completely without throwing a FormatException exception.

How do I convert DateTime to string in Python?

Conversion from datetime object to string You can convert datetime objects and pandas Timestamp object to string with str or the strftime method: %Y means four-digit year, %m presents two-digit month, %d describes two-digit day, %F is the shortcut for %Y-%m-%d .


3 Answers

It would be very hard to do this in a completely general way, but one option would be to extract the relevant DateTimeFormatInfo that you're interested in (using CultureInfo.DateTimeFormat), extract the culture-specific patterns from that (LongDatePattern, LongTimePattern etc), combine the patterns appropriately in some cases (e.g. ShortDatePattern space ShortTimePattern) and then try each pattern in turn using DateTime.TryParseExact - remembering to still specify the culture each time in order to handle date separators etc appropriately.

When DateTime.TryParseExact returns true, you know you've got a pattern which will parse the given text.

Sample code - including showing an example where you'd expect it to work but it doesn't:

using System;
using System.Collections.Generic;
using System.Globalization;

class Test
{
    static void Main()        
    {
        var us = new CultureInfo("en-US");
        var uk = new CultureInfo("en-GB");
        string text = "07/06/2013 11:22:11";

        // This one fails, as there's no appropriate time format
        Console.WriteLine(GuessPattern(text, us));
        // This one prints dd/MM/yyyy HH:mm:ss
        Console.WriteLine(GuessPattern(text, uk));
    }

    static string GuessPattern(string text, CultureInfo culture)
    {
        foreach (var pattern in GetDateTimePatterns(culture))
        {
            DateTime ignored;
            if (DateTime.TryParseExact(text, pattern, culture,
                                       DateTimeStyles.None, out ignored))
            {
                return pattern;
            }
        }
        return null;
    }

    static IList<string> GetDateTimePatterns(CultureInfo culture)
    {
        var info = culture.DateTimeFormat;
        return new string[]
        {
            info.FullDateTimePattern,
            info.LongDatePattern,
            info.LongTimePattern,
            info.ShortDatePattern,
            info.ShortTimePattern,
            info.MonthDayPattern,
            info.ShortDatePattern + " " + info.LongTimePattern,
            info.ShortDatePattern + " " + info.ShortTimePattern,
            info.YearMonthPattern
            // Consider the sortable pattern, ISO-8601 etc
        };        
    }
} 

You could potentially hard-code some "extra" date and time formats which you expect to work.

EDIT: To handle ambiguity, you could easily make GuessPattern return an IEnumerable<string> instead of a single string:

static IEnumerable<string> GuessPatterns(string text, CultureInfo culture)
{
    DateTime ignored;
    return GetDateTimePatterns(culture)
        .Where(pattern => DateTime.TryParseExact(text, pattern, culture,
                                             DateTimeStyles.None, out ignored))
    }
}
like image 142
Jon Skeet Avatar answered Sep 27 '22 22:09

Jon Skeet


You can have a set of predefined formats and parse the date and see if it passes, then you can get the string format you are looking for.

Refer to the answer but its in java - How to get the given date string format(pattern) in java?

like image 20
Carbine Avatar answered Sep 27 '22 23:09

Carbine


I had the same idea as Jon Skeet and went to implement it:

// Helper method
IEnumerable<string> DateTimeFormatPatterns(DateTimeFormatInfo format)
{
    var accessors = new Func<DateTimeFormatInfo, string>[]
    {
        f => f.FullDateTimePattern,
        f => f.LongDatePattern,
        f => f.LongTimePattern,
        f => f.MonthDayPattern,
        f => f.ShortDatePattern,
        f => f.SortableDateTimePattern,
        f => f.UniversalSortableDateTimePattern,
        f => f.YearMonthPattern,
    };

    return accessors.Select(accessor => accessor(format));
}

// The real function
string DetectDateTimeFormat(string date, CultureInfo culture)
{
    DateTime dummy;
    foreach (var pattern in DateTimeFormatPatterns(culture.DateTimeFormat))
    {
        if (DateTime.TryParseExact(date, pattern, culture,
                                   DateTimeStyles.None, out dummy))
        {
            return pattern;
        }
    }

    return null;
}

There is space for improvement here (e.g. the hardcoded DateTimeStyles.None doesn't help, an overload which assumes the current culture would also be useful), but you can use it like this:

var format = DetectDateTimeFormat("2012-12-08 15:00:00",
                                  CultureInfo.CurrentCulture);
like image 33
Jon Avatar answered Sep 27 '22 22:09

Jon