有谁知道 .NET 日期/时间解析器类似于 Ruby 的慢性病 (处理“明天”或“下周四下午 3 点”等内容)?

笔记:我确实编写了 Ruby(这就是我对 Chronic 的了解),但该项目必须使用 .NET。

有帮助吗?

解决方案

我们在内部项目中开发了您所需要的产品。如果有足够的需要,我们正在考虑将其公开。请查看此博客了解更多详细信息: http:// Precisionsoftwaredesign.com/blog.php.

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

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

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

该程序集位于下载部分,源代码可通过 Mercurial 获得。

其他提示

我不知道,但是有一个 Java 端口叫做 j慢性. 。如果不出意外的话,它可以为你自己提供一个很好的起点。或者也许您可以使用半自动 Java 到 C# 转换器,例如 章鱼 来帮助翻译它。(或者更好的东西,如果有人知道的话。)

好吧,另一个可能的途径:你可以使用慢性代码吗 铁红宝石?

存在 Chronic 的 .NET 端口。看 https://github.com/robertwilczynski/nChronic. 。我创建了它的一个分支,并进行了一些改进和错误修复,如下: https://github.com/dorony/nChronic (已发送拉取请求,作者仍未回复)。

@Blair Conrad - 好主意!我尝试让 Chronic 在 IronRuby 下运行,但遇到了一些依赖项问题 - 我不知道它是否已准备好。

我发现了一个项目 代码复合体 (日期时间英语解析器)正在尝试做同样的事情。它还不能处理几年或时间,但这是一个好的开始。我在这个项目上做了一些工作,并贡献了一个补丁来更好地处理书面数字。

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

有一个 类似的线程 早些时候,它提供了 CodeProject 上一个库的链接,该库似乎可以满足您的需求: http://www.codeproject.com/KB/edit/dateparser.aspx 但不幸的是,该库似乎是用 MFC 编写的,因此您必须用它创建一个 DLL,然后从 .NET 程序中调用它。

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

“今天下午2点”“星期二下午2点至2010年7月15日凌晨2点”“去年凌晨2点 - 明天14:30”“ 2010年7月18日下午2:45 pm”

将其放在 Codeplex 上,因为也许其他人会发现它有用。一探究竟: http://timestamper.codeplex.com/

我检查了几个框架和Python 解析日期时间 效果最好。可以使用 IronPython 从 .NET 使用它。

如果有人对完整的示例项目感兴趣,请对答案发表评论,我将尝试创建一个。

编辑

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

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

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

  • 2008年8月25日
  • 2008 年 8 月 25 日
  • 8月25日下午5点
  • 8 月 25 日下午 5 点
  • 下个星期六
  • 明天
  • 下周四下午 4 点
  • 下午 4 点
  • 爆炸物
  • 明天爆炸物
  • 星期二开斋节
  • 伊奥伊
  • 欧姆
  • 5分钟后
  • 5 分钟后
  • 5 小时前
  • 中午前2小时
  • 明天起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

它确实不像现有的那么复杂,但我想它工作得很好。可能是一个很好的扩展方法。

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

  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

我以为我也会尝试一下,直到我意识到!(虽然实施得很好)

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top