Skip to content

Instantly share code, notes, and snippets.

@wookay
Last active August 29, 2015 14:19
Show Gist options
  • Save wookay/7bf4d8c2afb35920f688 to your computer and use it in GitHub Desktop.
Save wookay/7bf4d8c2afb35920f688 to your computer and use it in GitHub Desktop.
12-hour clock format
# load Dates module
import Base.Dates: AbstractTime, Month, Millisecond, Year, TimeType, Day, Hour, Minute, Second, Period, periodisless, yearmonthday, days, hour, minute, second, millisecond, default
import Base.Dates: DelimitedSlot, Slot, DayOfWeekSlot, slotparse
import Base.Dates: DateFormat, duplicates
Base.show(io::IO,x::DateTime) = print(io,string(x))
DateTime(dt::AbstractString,df::DateFormat=ISODateTimeFormat) = DateTime(parse(dt,df)...)
function getslot(x,slot::DelimitedSlot,df,cursor)
endind = first(search(x,df.trans[slot.i],cursor+1))
if endind == 0 # we didn't find the next delimiter
s = x[cursor:end]
return (endof(x)+1, isdigit(s) ? slotparse(slot,s) : default(slot.period))
end
return endind+1, slotparse(slot,x[cursor:(endind-1)])
end
function parse(x::AbstractString,df::DateFormat)
x = strip(replace(x, r"#.*$", ""))
x = replace(x,df.begtran,"")
isempty(x) && throw(ArgumentError("Cannot parse empty format string"))
(typeof(df.slots[1]) <: DelimitedSlot && first(search(x,df.trans[1])) == 0) && throw(ArgumentError("Delimiter mismatch. Couldn't find first delimiter, \"$(df.trans[1])\", in date string"))
periods = Period[]
cursor = 1
for slot in df.slots
cursor, pe = getslot(x,slot,df,cursor)
pe != nothing && push!(periods,pe)
cursor > endof(x) && break
end
return sort!(periods,rev=true,lt=periodisless)
end
# base/dates/io.jl
immutable MeridianSlot <: AbstractTime end
slotparse(slot::Slot{MeridianSlot},x) = Hour(lowercase(x) == "pm" ? 12 : 0)
function DateFormat(f::AbstractString,locale::AbstractString="english")
slots = Slot[]
trans = []
begtran = match(r"^.*?(?=[ymuUdHMSsEea])",f).match
ss = split(f,r"^.*?(?=[ymuUdHMSsEea])")
s = split(begtran == "" ? ss[1] : ss[2],r"[^ymuUdHMSsEea]+|(?<=([ymuUdHMSsEea])(?!\1))")
for (i,k) in enumerate(s)
k == "" && break
tran = i >= endof(s) ? r"$" : match(Regex("(?<=$(s[i])).*(?=$(s[i+1]))"),f).match
slot = tran == "" || tran == r"$" ? FixedWidthSlot : DelimitedSlot
width = length(k)
typ = 'E' in k ? DayOfWeekSlot : 'e' in k ? DayOfWeekSlot :
'a' in k ? MeridianSlot :
'y' in k ? Year : 'm' in k ? Month :
'u' in k ? Month : 'U' in k ? Month :
'd' in k ? Day : 'H' in k ? Hour :
'M' in k ? Minute : 'S' in k ? Second : Millisecond
option = 'E' in k ? 2 : 'e' in k ? 1 :
'U' in k ? 2 : 'u' in k ? 1 : 0
push!(slots,slot(i,typ,width,option,locale))
push!(trans,tran)
end
duplicates(slots) && throw(ArgumentError("Two separate periods of the same type detected"))
return DateFormat(slots,begtran,trans)
end
# base/dates/types.jl
function DateTime(periods::Period...)
y = Year(1); m = Month(1); d = Day(1)
h = Hour(0); mi = Minute(0); s = Second(0); ms = Millisecond(0)
for p in periods
typeof(p) <: Year && (y = p)
typeof(p) <: Month && (m = p)
typeof(p) <: Day && (d = p)
typeof(p) <: Hour && (h += (h + p < Hour(24)) ? p : Hour(0))
typeof(p) <: Minute && (mi = p)
typeof(p) <: Second && (s = p)
typeof(p) <: Millisecond && (ms = p)
end
return DateTime(y,m,d,h,mi,s,ms)
end
import Base.Test: @test
f = "u dd, yyyy HH:MM:SS a"
@test string(Dates.DateTime("Apr 1, 2015 1:02:03 AM",DateFormat(f))) == "2015-04-01T01:02:03"
@test string(Dates.DateTime("Apr 1, 2015 1:02:03 PM",DateFormat(f))) == "2015-04-01T13:02:03"
@test string(Dates.DateTime("Apr 1, 2015 13:02:03 AM",DateFormat(f))) == "2015-04-01T13:02:03"
@test string(Dates.DateTime("Apr 1, 2015 13:02:03 PM",DateFormat(f))) == "2015-04-01T13:02:03"
@test string(Dates.DateTime("Apr 1, 2015 12:00:01 AM",DateFormat(f))) == "2015-04-01T12:00:01"
@test string(Dates.DateTime("Apr 1, 2015 12:00:00 AM",DateFormat(f))) == "2015-04-01T12:00:00"
@test string(Dates.DateTime("Apr 1, 2015 12:00:01 PM",DateFormat(f))) == "2015-04-01T12:00:01"
@test string(Dates.DateTime("Apr 1, 2015 12:00:00 PM",DateFormat(f))) == "2015-04-01T12:00:00"
f = "u dd, yyyy a HH:MM:SS"
@test string(Dates.DateTime("Apr 1, 2015 AM 1:02:03",DateFormat(f))) == "2015-04-01T01:02:03"
@test string(Dates.DateTime("Apr 1, 2015 PM 1:02:03",DateFormat(f))) == "2015-04-01T13:02:03"
@test string(Dates.DateTime("Apr 1, 2015 AM 13:02:03",DateFormat(f))) == "2015-04-01T13:02:03"
@test string(Dates.DateTime("Apr 1, 2015 PM 13:02:03",DateFormat(f))) == "2015-04-01T13:02:03"
@test string(Dates.DateTime("Apr 1, 2015 AM 12:00:01",DateFormat(f))) == "2015-04-01T12:00:01"
@test string(Dates.DateTime("Apr 1, 2015 AM 12:00:00",DateFormat(f))) == "2015-04-01T12:00:00"
@test string(Dates.DateTime("Apr 1, 2015 PM 12:00:01",DateFormat(f))) == "2015-04-01T12:00:01"
@test string(Dates.DateTime("Apr 1, 2015 PM 12:00:00",DateFormat(f))) == "2015-04-01T12:00:00"
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment