【问题标题】:Extracting datetime pattern from string based on culture基于文化从字符串中提取日期时间模式
【发布时间】:2021-04-13 00:38:42
【问题描述】:

我必须从字符串日期中提取日期时间模式。

例如 我有日期时间字符串“2020.01.01-09:20” 我使用文化解析这个字符串

var culture = new CultureInfo("en-us");
var date = "2020.01.01-09:20";
var isParsed = DateTime.TryParse(date, culture, DateTimeStyles.AdjustToUniversal, out var result);

结果正确。 现在我必须对日期和时间进行一些随机更改,并将其解析回字符串,并使用从原始字符串中提取的模式。

我制作了一个包含所有文化模式的方法

private 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,
        info.SortableDateTimePattern
    };
}

结果

foreach (var pattern in GetDateTimePatterns(culture))
    {
        Console.WriteLine(result.ToString(pattern ,culture));
    }

生成输出:

Wednesday, January 1, 2020 9:20:00 AM
Wednesday, January 1, 2020
9:20:00 AM
1/1/2020
9:20 AM
January 1
1/1/2020 9:20:00 AM
1/1/2020 9:20 AM
January 2020
2020-01-01T09:20:00

如您所见,没有与原始字符串相同的模式。

如何根据文化提取正确的模式?

【问题讨论】:

    标签: .net string datetime extract


    【解决方案1】:

    您似乎在使用自定义模式。您可以使用无限多的自定义模式,并且环境无法预见您可能使用的每一个模式。可能的解决方案

    您可以创建其他模式

    由于DateTimeFormatInfosealed,您可能无法创建继承自它的类,但您可以创建一个新类,具有您可能期望的模式属性。

    你可以使用 Levenshtein 的距离

    Levenshtein's distance 是从 string1 开始到达 string2 所需的单字符编辑次数。您可以为每个模式的版本计算输入字符串的距离并选择最小值,因为该模式是最接近的。

    【讨论】:

    • 但我不知道模式会是什么样子。它来自人类编写的 OCRed 文件。那不是任何标准。我有当它不被文化解析时特别创建的模式......然后我通过这个模式迭代并检查。但是当它被文化解析时,我必须根据文化中的模式重新创建字符串。
    • @HD 我的回答并没有假设您知道模式是什么。但是,如果对格式没有限制,那么就很难可靠地做任何事情。例如,01/02/03 可能意味着六个不同的事物,具体取决于年、月和日时段。因此,您可以比较 Levenshtein 的距离并选择最小值。但是,在我的示例中的格式中,除非您有更多信息,否则很难找出年、月和日。
    • 但是当我使用 Culture 将其解析为 DateTime 时,逻辑知道如何处理每个单独的“事物”。即使当我提取模式时,也存在一些问题不是 1:1 的问题。例如 SortableDateTimePattern: 'yyyy'-'MM'-'dd'T'HH':'mm':'ss' 包含 i 模式 T(终止符),可以是空格、下划线、连字符。因此,基于模式,我无法使用 chanded 值重新创建完全相同的字符串...因为解析正确处理输入字符串,所以它必须是一种提取可用模式以将其解析回字符串的方法
    • @HD 这就是为什么你需要找到 Levenshtein 距离。您的代码将不得不尝试几种组合。好吧,如果是四位数,那显然是一年。但如果是两位数,那么至少可以是一个月或一天。因此,您的算法将需要尝试从实际值中识别出可识别的内容。例如,“星期三”明确表示某一天,因此,如果输入包含 02,只要已经找到该天,那肯定不是一天。因此:1. 确定可识别的内容 2. 对不确定的内容进行连续猜测 3. 比较 Levenshtein 的猜测。
    • 老实说,我不知道如何使用 Levenstain 算法...我有原始字符串,您想使用文化中的所有模式生成字符串,然后选择一个距离最短的字符串...然后呢?
    猜你喜欢
    • 2020-08-14
    • 2011-03-31
    • 1970-01-01
    • 2023-01-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-03-18
    相关资源
    最近更新 更多