Analisador de data/hora em linguagem natural para .NET?[fechado]
Pergunta
Alguém conhece um analisador de data/hora .NET semelhante a Crônico para Ruby (lida com coisas como "amanhã" ou "15h na próxima quinta")?
Observação:Eu escrevo Ruby (que é como conheço o Chronic), mas este projeto deve usar .NET.
Solução
Desenvolvemos exatamente o que você procura em um projeto interno.Estamos pensando em tornar isso público se houver necessidade suficiente.Dê uma olhada neste blog para mais detalhes: http://precisionsoftwaredesign.com/blog.php.
Sinta-se à vontade para entrar em contato comigo se estiver interessado:contact@precisionsoftware.us
Esta biblioteca agora é um projeto do SourceForge.A página está em:
http://www.SourceForge.net/p/naturaldate
A montagem está na seção de downloads e o código-fonte está disponível no Mercurial.
Outras dicas
Não, mas há uma porta Java chamada jcrônico.No mínimo, poderia ser um bom ponto de partida para você.Ou talvez você possa usar um tradutor semiautomático de Java para C# como Polvo para ajudar a traduzi-lo.(Ou algo melhor, se alguém souber de alguma coisa.)
Ok, outro caminho possível:você poderia usar o código crônico usando FerroRubi?
Existe uma porta .NET do Chronic.Ver https://github.com/robertwilczynski/nChronic.Criei um fork dele com algumas melhorias e correções de bugs, aqui: https://github.com/dorony/nChronic (enviou pull requests, o autor ainda não respondeu).
@Blair Conrad - Boas ideias!Tentei fazer o Chronic rodar no IronRuby, mas tive alguns problemas com dependências - não sei se ele está pronto ainda.
Encontrei um projeto no Codeplex (DateTimeEnglishParser) que está tentando fazer a mesma coisa.Ainda não dá conta de anos ou tempo, mas é um bom começo.Trabalhei um pouco no projeto e contribuí com um patch para lidar melhor com os números escritos.
É um problema interessante e definitivamente me ajudou a entender melhor as expressões regulares, então acho que continuarei trabalhando nele.
Havia um tópico semelhante anteriormente e forneceu um link para uma biblioteca no CodeProject que parece fazer o que você deseja: http://www.codeproject.com/KB/edit/dateparser.aspx mas, infelizmente, a biblioteca parece estar escrita em MFC, então você teria que criar uma DLL e chamá-la no seu programa .NET.
Palmsey, recentemente tive o mesmo requisito, então fui em frente e escrevi um analisador simples.Não é o código mais legal, mas irá lidar com coisas como:
"Hoje às 14h" "Terça -feira às 14h - 15 de julho de 2010 às 2h" "Ano anterior às 2h - amanhã às 14h30" "18 de julho de 2010 às 14h45"
Coloque-o no codeplex, pois talvez alguém o considere útil.Confira: http://timestamper.codeplex.com/
Eu verifiquei vários frameworks e Python's AnalisarDataHora funcionou melhor.Ele pode ser usado no .NET usando IronPython.
Se alguém estiver interessado em um projeto de amostra completo, comente a resposta e tentarei criar um.
EDITAR
Conforme solicitado, aqui está um projeto simples que você pode usar com a biblioteca:
http://www.assembla.com/code/relativedateparser/subversion/nodes
Experimente o seguinte caso de uso, por exemplo:
- 25 de agosto de 2008
- 25 de agosto de 2008
- 25 de agosto, 17h
- 17h do dia 25 de agosto
- próximo sábado
- amanhã
- próxima quinta às 16h
- às 4 da tarde
- eod
- amanhã eod
- eod terça-feira
- ei
- eom
- em 5 minutos
- Daqui a 5 minutos
- 5 horas antes de agora
- 2 horas antes do meio-dia
- 2 dias a partir de amanhã
Não conheço nenhum, mas parecia um problema legal, então aqui está minha solução (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
Na verdade não é tão sofisticado quanto os que já existem, mas funciona bem, eu acho.Poderia ser um bom método de extensão.
@Burton:Acho que ele quis dizer o contrário, pelo menos pelo exemplo na página vinculada:
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
Pensei em tentar também até perceber!(boa implementação embora)