Repository: JuliaLang/julia
File: base/libc.jl (Julia)

Code before:
strptime(timestr::AbstractString) = strptime("%c", timestr)
function strptime(fmt::AbstractString, timestr::AbstractString)
    tm = TmStruct()
    r = ccall(:strptime, Cstring, (Cstring, Cstring, Ref{TmStruct}), timestr, fmt, tm)
    # the following would tell mktime() that this is a local time, and that
    # it should try to guess the timezone. not sure if/how this should be
    # exposed in the API.
    # tm.isdst = -1
    if r == C_NULL
        # TODO: better error message
        throw(ArgumentError("invalid arguments"))
    end
    @static if Sys.isapple()
        function shouldcallmktime(s::AbstractString)
            # Equivalent to !occursin(r"([^%]|^)%(a|A|j|w|Ow)"a, s), but
            # without regex since this is not available yet

            c = Base.utf8units(s)
            N = length(c)
            i = findfirst(==(UInt8('%')), c)

            while true
                isnothing(i) && break
                i >= N && break
                # Ignore % following after another %
                if !(i >= firstindex(c)+1 && c[i-1] == UInt8('%'))
                    # Detect %a, %A, %j, %w, %Ow
                    if c[i+1] in b"aAjw" || (i <= N-2 && c[i+1:i+2] == b"Ow")
                        return false
                    end
                end

                i = findnext(==(UInt8('%')), c ,i+1)
            end
            return true
        end
        # if we didn't explicitly parse the weekday or year day, use mktime
        # to fill them in automatically.
        if shouldcallmktime(fmt)
            ccall(:mktime, Int, (Ref{TmStruct},), tm)
        end
    end
    return tm
end

# system date in seconds

"""
    time(t::TmStruct)::Float64

Convert a `TmStruct` struct to a number of seconds since the epoch.

Review comment (suggestion):
```suggestion
                if !(i > firstindex(c) && c[i-1] == UInt8('%'))
```

Code after:
strptime(timestr::AbstractString) = strptime("%c", timestr)
function strptime(fmt::AbstractString, timestr::AbstractString)
    tm = TmStruct()
    r = ccall(:strptime, Cstring, (Cstring, Cstring, Ref{TmStruct}), timestr, fmt, tm)
    # the following would tell mktime() that this is a local time, and that
    # it should try to guess the timezone. not sure if/how this should be
    # exposed in the API.
    # tm.isdst = -1
    if r == C_NULL
        # TODO: better error message
        throw(ArgumentError("invalid arguments"))
    end
    @static if Sys.isapple()
        function shouldcallmktime(s::AbstractString)
            # Equivalent to !occursin(r"([^%]|^)%(a|A|j|w|Ow)"a, s), but
            # without regex since this is not available yet

            c = Base.utf8units(s)
            N = length(c)
            i = findfirst(==(UInt8('%')), c)

            while true
                isnothing(i) && break
                i >= N && break

                # Ignore % following after another %
                if i == firstindex(c) || c[i-1] != UInt8('%')
                    # Detect %a, %A, %j, %w, %Ow
                    if c[i+1] in b"aAjw"
                        return false
                    end
                    if (checkbounds(Bool, c, i+2) &&
                        c[i+1] == UInt8('O') &&
                        c[i+2] == UInt8('w')
                    )
                        return false
                    end
                end

                i = findnext(==(UInt8('%')), c, i+1)
            end
            return true
        end
        # if we didn't explicitly parse the weekday or year day, use mktime
        # to fill them in automatically.
        if shouldcallmktime(fmt)
            ccall(:mktime, Int, (Ref{TmStruct},), tm)
        end
    end
    return tm
end