Feature #21533
closedIntroduce `Time#am?` and `Time#pm?`
Description
This proposal adds two predicate methods to Time
:
Time.utc(2000, 1, 1, 11, 59, 59).am? # => true
Time.utc(2000, 1, 1, 12, 0, 0).pm? # => true
-
am?
returns true when the hour is less than 12. -
pm?
returns true when the hour is 12 or greater.
These methods provide a clear and expressive way to branch logic based on time of day. For example:
def reminder_deferral_options
options = []
options << ["Later today", "later_today"] if Time.now.am?
options << ["Tomorrow morning", "tomorrow_morning"]
options << ["Pick a date/time…", "custom"]
options
end
This is a common pattern in applications involving reminders and scheduling. The
method names are intuitive, and the semantics are well understood.
The implementation is in this Pull Request.
Updated by nobu (Nobuyoshi Nakada) 22 days ago
I'm not against the methods themselves, since there are similar methods such as monday?
, tuesday?
, and so on.
(no january?
, february?
, etc though)
But your example, selecting by am?
, seems less convincing.
What will you do if the criteria is changed, or more options are added?
Add morning?
, daytime?
, and others?
def reminder_deferral_options
now = Time.now
options = []
options << ["Around noon", "around_noon"] if now.morning?
options << ["Later today", "later_today"] if now.am?
options << ["Tonight", "tonight"] if now.daytime?
options << ["Tomorrow morning", "tomorrow_morning"]
options << ["Pick a date/time…", "custom"]
options
end
Updated by matheusrich (Matheus Richard) 22 days ago
· Edited
@nobu (Nobuyoshi Nakada) totally fair questioning. In fact, my initial idea was to propose Time#morning? (hour between 6...12) but I wasn't sure that would be true for all cultures.
Time#am?/pm?
are enough for my use case, and I think they have value in themselves.
I'd be happy to introduce any other methods like daytime?/nighttime?, but I think those are prone to bikeshedding for what day/night/morning means. Am/pm are clearly defined and might be enough most of the time?
Updated by nobu (Nobuyoshi Nakada) 21 days ago
matheusrich (Matheus Richard) wrote in #note-2:
@nobu (Nobuyoshi Nakada) (Nobuyoshi Nakada) totally fair questioning. In fact, my initial idea was to propose Time#morning? (hour between 6...12) but I wasn't sure that would be true for all cultures.
It varies by cultures.
I'd be happy to introduce any other methods like daytime?/nighttime?, but I think those are prone to bikeshedding for what day/night/morning means.
Agree.
We would need methods to calculate the sunrise/sunset times for a specified date and location.
Am/pm are clearly defined and might be enough most of the time?
Cleary defined -- probably yes.
Enough most of the time -- depends on cultures probably.
In any case, I'm not against (neutral or slightly positive) this proposal itself, as wrote previously.
Updated by mame (Yusuke Endoh) 21 days ago
I'm not strongly opposed, but I have a slight doubt about noon.pm?
returning true
.
According to NIST, designating noon as either a.m. or p.m. is technically incorrect:
https://www.nist.gov/pml/time-and-frequency-division/times-day-faqs
To illustrate this, consider that "a.m." and "p.m." are abbreviations for "ante meridiem" and "post meridiem," which mean "before noon" and "after noon," respectively. Since noon is neither before noon nor after noon, a designation of either a.m. or p.m. is incorrect. Also, midnight is both twelve hours before noon and twelve hours after noon.
A quick search for "12 p.m. noon" also brings up many articles and discussions arguing against the usage. I'm curious what others think.
Updated by matheusrich (Matheus Richard) 20 days ago
The current implementation is consistent with strftime:
noon = Time.new(2025, 1, 1, 12, 0, 0)
midnight = Time.new(2025, 1, 1, 0, 0, 0)
puts noon.strftime("%I:%M %p").downcase # => 12:00 pm
puts midnight.strftime("%I:%M %p").downcase # => 12:00 am
Updated by duerst (Martin Dürst) 20 days ago
Using 12pm for noon is indeed bad practice. Using 12am for midnight is even worse practice, because without context it's unclear whether it's at the beginning or the end of a certain date.
But it is practice, at least in certain parts of the world. See e.g. the Caltrain schedule at https://www.caltrain.com/media/34716. There's e.g. a northbound train that leaves South San Francisco (S. San Francisco) at 12:00pm on the first page. On page 2, there's also a train that leaves Menlo Park at 12:00am. In both cases, the context make it clear what is meant.
I don't think introducing the two methods is a good idea. Formatting times should be done with an appropriately internationalized library. In other cases, what is in the morning or the afternoon may vary widely. The usage example given by the OP is spurious; the possibility to do something "Later today" may end at 11:00 or at 13:00 or at some other time somewhere around noon.
Updated by matheusrich (Matheus Richard) 7 days ago
· Edited
Formatting times should be done with an appropriately internationalized library.
This is not formatting. This is intended for querying, much like we have monday?
and other methods.
The usage example given by the OP is spurious; the possibility to do something "Later today" may end at 11:00 or at 13:00 or at some other time somewhere around noon.
I'm sorry, I don't follow. The possibility to do something "Later today" will last until 11:59, which is the last am?
time.
It would be a bummer if the whole proposal was rejected over a minor edge-case of 12pm/12am. I propose two alternatives:
- Returning
false
inam?/pm?
both on noon and midnight, as there are no consensus what those mean. - Adding supporting methods
noon?
andmidgnight?
to help users disambiguate and deal with these edge cases as they see fit.
Updated by naruse (Yui NARUSE) 7 days ago
- Status changed from Open to Rejected
We discussed about the edge cases 00:00 and 12:00 in developer meeting.
After some discussion we concluded there is no consensus whether 00:00 and 12:00 are a.m. or p.m.
For example U.S. Government Publishing Office, they changed the definition in 2008.
It feels it is still unstable.
https://en.wikipedia.org/wiki/12-hour_clock#Confusion_at_noon_and_midnight
Updated by naruse (Yui NARUSE) 7 days ago
matheusrich (Matheus Richard) wrote in #note-7:
It would be a bummer if the whole proposal was rejected over a minor edge-case of 12pm/12am. I propose two alternatives:
- Returning
false
inam?/pm?
both on noon and midnight, as there are no consensus what those mean.- Adding supporting methods
noon?
andmidgnight?
to help users disambiguate and deal with these edge cases as they see fit.
There is no consensus that it can return false for Time.utc(2000, 1, 1, 12, 0, 0).am? and pm?.
If you want to check it is am, you can compare time.hour < 12 while you are satisfied with this definition.