I am working on a form widget for users to enter a time of day into a text input (for a calendar application). Using JavaScript (we are using jQuery FWIW), I want to find the best way to parse the text that the user enters into a JavaScript Date()
object so I can easily perform comparisons and other things on it.
I tried the parse()
method and it is a little too picky for my needs. I would expect it to be able to successfully parse the following example input times (in addition to other logically similar time formats) as the same Date()
object:
- 1:00 pm
- 1:00 p.m.
- 1:00 p
- 1:00pm
- 1:00p.m.
- 1:00p
- 1 pm
- 1 p.m.
- 1 p
- 1pm
- 1p.m.
- 1p
- 13:00
- 13
I am thinking that I might use regular expressions to split up the input and extract the information I want to use to create my Date()
object. What is the best way to do this?
Compilation table of other answers
First of all, I can't believe that there is not a built-in functionality or even a robust third-party library that can handle this. Actually, it's web development so I can believe it.
Trying to test all edge cases with all these different algorithms was making my head spin, so I took the liberty of compiling all the answers and tests in this thread into a handy table.
The code (and resulting table) is pointlessly large to include inline, so I've made a JSFiddle:
http://jsfiddle.net/jLv16ydb/4/show
Please feel free to fork my fiddle and add more algorithms and test cases
I didn't add any comparisons between the result and the "expected" output, because there are cases where the "expected" output could be debated (eg, should
12
be interpreted as12:00am
or12:00pm
?). You will have to go through the table and see which algorithm makes the most sense for you.Note: The colors do not necessarily indicate quality or "expectedness" of output, they only indicate the type of output:
red
= js error thrownyellow
= "falsy" value (undefined
,null
,NaN
,""
,"invalid date"
)green
= jsDate()
objectlight green
= everything elseWhere a
Date()
object is the output, I convert it to 24 hrHH:mm
format for ease of comparison.Here's an improvement on Joe's version. Feel free to edit it further.
Changes:
I came across a couple of kinks in implementing John Resig's solution. Here is the modified function that I have been using based on his answer:
If you only want seconds here is a one liner
After thoroughly testing and investigating through my other compilation answer, I concluded that @Dave Jarvis's solution was the closest to what I felt were reasonable outputs and edge-case-handling. For reference, I looked at what Google Calendar's time inputs reformatted the time to after exiting the text box.
Even still, I saw that it didn't handle some (albeit weird) edge cases that Google Calendar did. So I reworked it from the ground up and this is what I came up with. I also added it to my compilation answer.
I feel that this is the closest I can get for my needs, but suggestions are welcome. Note: This is American-centric in that it defaults to am/pm for certain patterns:
1
=>13:00
(1:00pm
)1100
=>23:00
(11:00pm
)456
=>16:56
(4:56pm
)A quick solution which works on the input that you've specified:
It should work for a few other varieties as well (even if a.m. is used, it'll still work - for example). Obviously this is pretty crude but it's also pretty lightweight (much cheaper to use that than a full library, for example).