bitwalker / timex

A complete date/time library for Elixir projects.
https://hexdocs.pm/timex
MIT License
1.75k stars 375 forks source link

RFC: Human readable duration parsing for Timex.Duration #362

Open cevn opened 7 years ago

cevn commented 7 years ago

Similar to Ruby's ChronicDuration gem, I need an elixir library that will support parsing natural language. Since Timex can output in a human readable format, it seems like it would make sense to be able to parse in such a way as well. Thoughts?

require 'chronic_duration'
=> true
>> ChronicDuration.parse('4 minutes and 30 seconds')
=> 270
>> ChronicDuration.parse('0 seconds')
=> nil
>> ChronicDuration.parse('0 seconds', :keep_zero => true)
=> 0
bitwalker commented 6 years ago

A naive recursive descent parser for this would be relatively easy to put together, and if I recall correctly, my example for creating custom formatters/parsers actually builds one. That said, to properly handle natural language, we'd probably want a basic implementation of an Earley parser which can properly handle ambiguous context-free grammars. I've had this on my todo list for a long time, but haven't had time to implement it. I'm certainly open to working with anyone interested on getting an implementation built and merged!

bitwalker commented 6 years ago

I just realized you specified this for durations only, so that simplifies things a bit, I suspect the naive approach might be enough to satisfy the requirements.

suprnova32 commented 6 years ago

I wanted the same functionality, so I decided to port some of the ChronicDuration functionality and add it to my project. https://github.com/AlloyCI/alloy_ci/blob/master/lib/alloy_ci/lib/time_convert.ex#L36-L53

It covers around 90% of the use cases for which you would use ChronicDuration.parse. To simplify it, I removed the possibility to use the words and, plus, and with to join the time units.

I also does not assume that a time unit without a number defaults to 1, so hour 5 minutes will not default to 1 hour 5 minutes, instead it will only parse the 5 minutes. For most use cases this should be fine.

@bitwalker I was thinking about adding this code to Timex but couldn't figure out the best place to put it. Any suggestions?

ccapndave commented 3 years ago

Thanks for this!