.NET的自然语言日期/时间解析器?

时间:2008-08-22 22:45:11

标签: .net datetime nlp

有没有人知道类似于Chronic for Ruby的.NET日期/时间解析器(处理诸如“明天”或“下周四下午3点”之类的东西)?

注意:我写Ruby(这是我对Chronic的了解),但这个项目必须使用.NET。

9 个答案:

答案 0 :(得分:11)

我们在内部项目中精确地开发了您正在寻找的东西。如果有足够的需要,我们正在考虑将其公之于众。请查看此博客以获取更多详细信息:http://precisionsoftwaredesign.com/blog.php

如果您有兴趣,请随时与我联系:contact@precisionsoftware.us

此库现在是SourceForge项目。该页面位于:

http://www.SourceForge.net/p/naturaldate

程序集位于下载部分,Mercurial提供了源代码。

答案 1 :(得分:5)

我没有,但有一个名为jchronic的Java端口。如果没有别的,它可以为你自己提供一个很好的起点。或许你可以使用像Octopus这样的半自动Java到C#翻译来帮助翻译它。 (或者更好的东西,如果有人知道的话。)

好的,另一种可能的途径:您可以使用IronRuby

来使用慢性代码吗?

答案 2 :(得分:5)

存在慢性的.NET端口。见https://github.com/robertwilczynski/nChronic。我创建了一个带有一些改进和错误修复的分支,在这里:https://github.com/dorony/nChronic(发送拉请求,作者仍然没有回应)。

答案 3 :(得分:4)

@Blair Conrad - 好主意!我试图让Chronic在IronRuby下运行但是在依赖项方面存在一些问题 - 我不知道它已经准备好了。

我在CodeplexDateTimeEnglishParser)上找到了一个试图做同样事情的项目。它没有处理数年或时间,但它是一个良好的开端。我已经为这个项目做了一些工作,并提供了一个补丁来更好地处理书面数字。

这是一个有趣的问题,并且确实帮助我更好地理解正则表达式,所以我想我会继续努力。

答案 4 :(得分:3)

之前有一个similar thread,它提供了一个链接到CodeProject上的库,它似乎可以做你想要的:http://www.codeproject.com/KB/edit/dateparser.aspx但不幸的是这个库似乎是用MFC编写的,所以你必须从中创建一个DLL,然后从.NET程序中调用它。

答案 5 :(得分:3)

Palmsey,我最近也有同样的要求所以我继续编写了一个简单的解析器。它不是最好的代码,但它会处理类似的事情:

“今天下午2点” “星期二下午2点 - 2010年7月15日凌晨2点” “上一年凌晨2点 - Tommorow 14:30” “2010年7月18日下午2:45”

把它放在codeplex上,因为也许别人会发现它很有用。看看:http://timestamper.codeplex.com/

答案 6 :(得分:3)

我检查了几个框架,Python的ParseDateTime效果最好。它可以使用IronPython从.NET中使用。

如果有人对完整的示例项目感兴趣,请对答案进行评论,然后我会尝试创建一个。

修改

根据要求,这是一个可以与库一起使用的简单项目:

http://www.assembla.com/code/relativedateparser/subversion/nodes

尝试以下用法案例,例如:

  • 2008年8月25日
  • 2008年8月25日
  • 8月25日下午5点
  • 8月25日下午5点
  • 下周六
  • 明天
  • 下周四下午4点
  • 下午4点
  • EOD
  • 明天eod
  • eod tuesday
  • EOY
  • EOM
  • 在5分钟内
  • 从现在起5分钟
  • 现在提前5小时
  • 中午前2小时
  • 明天起2天

答案 7 :(得分:2)

我不知道一个,但它听起来像一个很酷的问题,所以这就是我对它的打击(VB.NET):

Private Function ConvertDateTimeToStringRelativeToNow(ByVal d As DateTime) As String
    Dim diff As TimeSpan = DateTime.Now().Subtract(d)
    If diff.Duration.TotalMinutes < 1 Then Return "Now"

    Dim str As String
    If diff.Duration.TotalDays > 365 Then
        str = CInt(diff.Duration.TotalDays / 365).ToString() & " years"
    ElseIf diff.Duration.TotalDays > 30 Then
        str = CInt(diff.TotalDays / 30).ToString() & " months"
    ElseIf diff.Duration.TotalHours > 24 Then
        str = CInt(diff.Duration.TotalHours / 24) & " days"
    ElseIf diff.Duration.TotalMinutes > 60 Then
        str = CInt(diff.Duration.TotalMinutes / 60) & " minutes"
    Else
        str = CInt(diff.Duration.TotalMinutes).ToString() & " minutes"
    End If
    If str.StartsWith("1") Then str = str.SubString(0, str.Length - 1)
    If diff.TotalDays > 0 Then
        str &= " ago"
    Else
        str &= " from now"
    End If
    Return str
End Function

它确实没有已经存在的那么复杂,但我认为它可以正常工作。可能是一个不错的扩展方法。

答案 8 :(得分:1)

@ Burton:我认为他的意思是另一种方式,至少从链接页面上的例子来看:

  Chronic.parse('tomorrow')
    #=> Mon Aug 28 12:00:00 PDT 2006

  Chronic.parse('monday', :context => :past)
    #=> Mon Aug 21 12:00:00 PDT 2006

  Chronic.parse('this tuesday 5:00')
    #=> Tue Aug 29 17:00:00 PDT 2006

在我意识到之前,我还以为我会刺伤它! (尽管很好实现)