bear / parsedatetime

Parse human-readable date/time strings
Apache License 2.0
695 stars 106 forks source link

12-hour versus 24-hour (interpreting 12-hour times without explicit am/pm meridian) #210

Open zefoo opened 7 years ago

zefoo commented 7 years ago

Is it possible to set 12 hour parsing versus 24 hour parsing? eg. someone says 1:00 and it gets parsed as 1am, when they mean 1pm. If I could pass a constant that says to set 12 or 24 hour time, that would be ideal I imagine. I tried to find it, and looked through previous issues, but didn't have much luck.

Any quick two cents? Thank you.

philiptzou commented 7 years ago

So in my opinion normally we can safely call 1:00 ~ 6:00 without am/pm in most circumstances as pm by default.

Perhaps we can provide an optional parameter for users who wants to set up a customized time range in a day that can be treated as time in am or pm.

zefoo commented 7 years ago

Thank you Philip for chiming in.

I agree. 7 could be 7am or 7pm, as well as 8-10 I'd say.

If this were to be an optional parameter, I wonder how it'd work. startSafeHour endSafeHour parameters, perhaps? Maybe something like this...

Define a safe start/end hour. Say, 6am to 9pm. If the user is being vague, then default to within this window. eg. 5:00 means 5:00pm. And anything 1:00-6:00 per your comment.

Alternative could be the inverse... but this safe start / end sounds much more intuitive.

idpaterson commented 7 years ago

I'm curious about the use case, are you processing existing text or is this for active user input relative to the current time? There may be some consideration of the current time required... if it's 5am now and I write "breakfast at 6" I probably mean 6am but at noon "yoga at 6" probably means 6pm. However, for example if your implementation is a diary rather than a task scheduler the user will generally be speaking about the past and you may want this logic to work differently.

Consider a similar problem at a yearly granularity. In November 2016 if I reference "January 12" am I referring to January 2016 or 2017? It depends on the context and different implementations will have different answers for that depending on whether they normally expect past or future date references. I believe that the default is to assume the next occurrence, so in this example January 12, 2017.

Extrapolating that to the time of day case, is it desirable for a setting to control whether "meet at 8:30" means 8:30am when it is before that time otherwise it means 8:30pm? When it is after 8:30PM does "8:30" refer to 8:30am of the following day?

See the comments for YearParseStyle and DOWParseStyle, this seems like it may be the same concept at a different granularity.

zefoo commented 7 years ago

Great points here Ian. Tying context (eg. breakfast means AM) to this sounds like a different ballgame (and a fun challenge, ha). For my use case, this is for active user input relative to current time.

For how we specifically get the string to parse, the user does only mention time, and it's a time in the future. It can be thought of as a follow up time.

Correct, the next occurrence is always what is desired in my use case, so the default does the trick (and we pass a sourceTime arg).

Per "8:30" getting passed, within the example previously mentioned if we have a safeStartHour set to 6:00 and a safeEndHour set to 21:00/9pm, I would see cal.parseDT() return 0 for the parse status, meaning it wasn't parsed because it wasn't understood. Whereas, if someone passed "1:00" (with previous safe hours), it returns to 13:00 or 1pm, since the alternative is outside of the safe hours. This way, if 0 is returned as parse status, we can prompt user to clarify. Also, we can have the users set their own start/end hours if we see some people are night hours, ha.

I was thinking this could work similar to the YearParseStyle and DOWParseStyle as well.

idpaterson commented 7 years ago

Sorry, "breakfast at 6" was a bad example since parsedatetime already interprets "breakfast" as a time. I was trying to point out that when it's currently 5am, is 6:00 more likely to mean 6:00 or 18:00? I think that following the pattern of YearParseStyle and DOWParseStyle would be good.

Also related, it would be useful for pdtContext to include a flag to indicate whether the user specified the am/pm meridian.

bear commented 7 years ago

Also related, it would be useful for pdtContext to include a flag to indicate whether the user specified the am/pm meridian.

yes please!

zefoo commented 7 years ago

Hey Ian, re this: "I was trying to point out that when it's currently 5am, is 6:00 more likely to mean 6:00 or 18:00?"

In my use case, since time is relative to user preference, this becomes more of a question on what the user's "safe times" are. Having said that, the way I see this is that if user safe start time was 5:00/5am and a safeEndHour set to 21:00/9pm, and the user said 6:00, I'd like to see the parse_status returned as 0 (if safe hours were set). This would allow the code to then prompt the user to be more specific because such input would be truly vague.

Can you elaborate on how you see this? "Also related, it would be useful for pdtContext to include a flag to indicate whether the user specified the am/pm meridian."

Are you saying, that if user says 5:00 then if pdtContext flag was set to PM it would automatically default to 5pm?

idpaterson commented 7 years ago

pdtContext is actually an indication of the components included in the original phrase, so having a flag in there to specify whether or not the parsed phrase included the am/pm meridian would allow developers to more easily implement custom handling. For instance, if the safe times concept was not implemented directly in parsedatetime, you could at least implement some code to check the context and adjust the parsed time based on your application's preferences.

So, when the date "1:12 pm" is parsed you would get a pdtContext specifying that the hour, minute, and meridian were set whereas parsing "1:12" would give you a pdtContext specifying that only the hour and minute were set. An application could check for that case and adjust the parsed time as needed.

idpaterson commented 7 years ago

Oops, clicked the wrong button!

zefoo commented 7 years ago

Thank you Ian for explaining. That makes sense. Another idea would be, if parse status result was for date and/or datetime, I could strip the time out and if the time is outside of safe Hours (9pm to 6am, say), then I could ask the user, "Are you sure this is the correct time you want? It seems late/early." – or such. I'm not sure how much of this functionality would actually be useful to others at this point (and I greatly appreciate the dialog thus far).