分析日期时间格式以获取格式字符串

本文关键字:格式 字符串 获取 时间 日期 | 更新日期: 2023-09-27 18:32:01

我希望能够从日期时间字符串中获取格式字符串

例如

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

"2013/30/01 16:00" => "yyyy/日/月亮 HH:mm"

这可能吗?

分析日期时间格式以获取格式字符串

完全通用的方式执行此操作非常困难,但一种选择是提取您感兴趣的相关DateTimeFormatInfo(使用 CultureInfo.DateTimeFormat),从中提取特定于文化的模式(LongDatePatternLongTimePattern等),在某些情况下适当地组合模式(例如 ShortDatePattern空格 ShortTimePattern),然后使用 DateTime.TryParseExact 依次尝试每种模式 - 请记住每次仍指定区域性,以便适当地处理日期分隔符等。

DateTime.TryParseExact返回true时,你知道你有一个模式来解析给定的文本。

示例代码 - 包括显示您希望它工作但无法工作的示例:

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
        };        
    }
} 

您可能会对一些您希望工作的"额外"日期和时间格式进行硬编码。

编辑:为了处理歧义,您可以轻松地GuessPattern返回一个IEnumerable<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))
    }
}

您可以拥有一组预定义的格式并解析日期并查看它是否通过,然后您可以获得所需的字符串格式。

参考答案,但它在java中 - 如何在java中获取给定的日期字符串格式(模式)?

我和Jon Skeet有同样的想法,并去实现它:

// 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;
}

这里有改进的空间(例如,硬编码DateTimeStyles.None没有帮助,假设当前文化也很有用的重载),但你可以像这样使用它:

var format = DetectDateTimeFormat("2012-12-08 15:00:00",
                                  CultureInfo.CurrentCulture);

你可以尝试通过编写下面的代码来获取yyyy/dd/MM HH:mm格式。

DateTimeFormatInfo df1 = new DateTimeFormatInfo();
df1.SortTimePattern();

它将为您提供相同的HH:mm格式。