Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add am/pm to DateFormat #23870

Closed
ChristianKurz opened this issue Sep 25, 2017 · 9 comments · Fixed by #32308
Closed

Add am/pm to DateFormat #23870

ChristianKurz opened this issue Sep 25, 2017 · 9 comments · Fixed by #32308
Labels
dates Dates, times, and the Dates stdlib module feature Indicates new feature / enhancement requests stdlib Julia's standard library

Comments

@ChristianKurz
Copy link
Contributor

currently, DateFormat does not support am/pm. As this format is often used, it would be useful to be able to convert it to DateTime.

For Minutes after midday (e.g. 12:0-12:59 AM) and after midnight (0:01-0:59 PM), the am/pm-rule is a bit strange. Support in DateTime could help prevent bugs.

@fredrikekre fredrikekre added the dates Dates, times, and the Dates stdlib module label Sep 25, 2017
@KlausC
Copy link
Contributor

KlausC commented Oct 1, 2017

This should be done in a standard package, not in base (#23302).

It seems rather unclear to me, what would be the "US-Standard" notation. At least ""0:01 PM" seems a mixture of 12-hour clocks and 24-hour clocks.
See https://en.wikipedia.org/wiki/12-hour_clock#Confusion_at_noon_and_midnight

@mikesafar
Copy link

mikesafar commented Oct 1, 2018

This seems like a big gap here in this library. In my view, there is no question: 12:00 am is midnight, 12 PM is noon. It is true that many programmers make deterministic statements that, for example 11:59:59 is "end of day", but this is to avoid overlap of data that may try to capture >= 12:00 AM, with a margin of error of 1 second (which by the way is insufficient in a variety of high-precision applications). Not having this support means fundamentally more checking in the client code.

Most systems follow this assumption.

BTW: AM/PM are Latin abbreviations:

AM = Ante meridiem: Before noon
PM = Post meridiem: After noon

But if you make the assumption that all the time "labeled" as 12 is in the same AM/PM designation, then you're good.

@mikesafar
Copy link

mikesafar commented Oct 1, 2018

For those interested, I wrote a handler for this case:

using Dates

function _parse_datetime_ampm(ds::String, fmt::DateFormat)::DateTime
    m = match(r"(.*\d{4}\s?\d{1,2}:\d{2})(\s?)(AM|PM)?"i, ds)
    dt = DateTime(m.captures[1], fmt) 
    ampm = m.captures[3]
    dt += (ampm != nothing && uppercase(ampm) == "PM" && Hour(dt).value != 12) ? Hour(12) : Hour(0)
end

dx = ["June 3, 2009 8:40 PM", "January 26, 2018 3:20 AM", "January 26, 2018 3:20AM", "January 26, 2018 3:20PM", "January 26, 2018 3:20", "April 1, 2000 12:01pm"]
x = _parse_datetime_ampm.(dx, dateformat"U d, y H:M")

@StefanKarpinski StefanKarpinski added feature Indicates new feature / enhancement requests stdlib Julia's standard library dates Dates, times, and the Dates stdlib module and removed dates Dates, times, and the Dates stdlib module labels Oct 1, 2018
@stevengj
Copy link
Member

stevengj commented Nov 9, 2018

In Java, 12pm is noon. In Python, dateutil.parser also gives noon—the relevant code was apparently added without much discussion back in 2003. For the glibc strftime function, 12pm is noon, and similarly for musl and BSD libc, although the POSIX standard for strftime does not seem to specify a behavior. In Ruby, they have their own strftime implementation which also uses 12pm==noon.

In short, while 12am/pm are technically ambiguous and "should not be used" according to NIST, I haven't yet been able to find any widely used software library or language that deviates from 12pm==noon.

@StefanKarpinski
Copy link
Member

It seems to be very widely used in practice that 12 pm is noon and 12 am is midnight. Indeed, it would be very jarring—discontinuous, technically—otherwise since 12:01 pm is definitely in one minute after noon and 12:01 am is definitely one minute after midnight. It's far less weird to have an am/pm discontinuity between 11:59 pm and 12:00 am and likewise between 11:59 am and 12:00 pm.

@maxbennedich
Copy link
Contributor

The above code is incorrect for "12 AM". As is this code which is based on it. This code suggested on Discourse today is wrong for both 12 AM and 12 PM. This really needs to be supported by the parser since it's too easy for users to mess up if doing oneself. Until then, if anyone else finds this issue, here's a (hopefully) corrected version of the above code:

using Dates

function parse_datetime_ampm(ds::AbstractString, fmt::DateFormat)
    m = match(r"(.*?)\s*(AM|PM)?$"i, ds)
    d = DateTime(m.captures[1], fmt)
    ampm = uppercase(something(m.captures[2], ""))
    d + Hour(12 * +(ampm == "PM", ampm == "" || hour(d) != 12, -1))
end

dx = [
    "May 1, 2001 12:15am",
    "May 1, 2001 00:15",
    "May 1, 2001 1:15 AM",
    "May 1, 2001 01:15",
    "May 1, 2001 12:15 pm",
    "May 1, 2001 12:15",
    "May 1, 2001 1:15PM",
    "May 1, 2001 13:15"]

println.(parse_datetime_ampm.(dx, dateformat"U d, y H:M"));

@galenlynch
Copy link
Contributor

I would really appreciate it if this were handled in the Dates standard library.

@stevengj
Copy link
Member

stevengj commented Jun 9, 2019

I think this is just waiting for someone to make a PR; the consensus seems to be in favor.

@stevengj
Copy link
Member

stevengj commented Jun 13, 2019

Note that you can use Libc.strptime to do this already:

julia> Time(Libc.strptime("%I:%M%p", "12:03am"))
00:03:00

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
dates Dates, times, and the Dates stdlib module feature Indicates new feature / enhancement requests stdlib Julia's standard library
Projects
None yet
Development

Successfully merging a pull request may close this issue.

8 participants