diff --git a/base/dates/conversions.jl b/base/dates/conversions.jl index 22614f355f94d..22b0819b7b18c 100644 --- a/base/dates/conversions.jl +++ b/base/dates/conversions.jl @@ -31,30 +31,10 @@ Base.convert(::Type{DateTime}, dt::Date) = DateTime(UTM(value(dt)*86400000)) Base.convert(::Type{Date}, dt::DateTime) = Date(UTD(days(dt))) Base.convert(::Type{Time}, dt::DateTime) = Time(Nanosecond((value(dt) % 86400000) * 1000000)) -""" - convert{T<:Real}(::Type{T}, dt::DateTime) -> T -Converts a DateTime value `dt` to a number of type `T`. The returned value corresponds to the number of Rata Die milliseconds since epoch. -See `convert(DateTime, x::Real)` for inverse. -""" -Base.convert{R<:Real}(::Type{R},x::DateTime) = convert(R,value(x)) -""" - convert{T<:Real}(::Type{T}, dt::Date) -> T -Converts a Date value `dt` to a number of type `T`. The returned value corresponds to the number of Rata Die days since epoch. -See `convert(Date, x::Real)` for inverse. -""" -Base.convert{R<:Real}(::Type{R},x::Date) = convert(R,value(x)) -""" - convert{T<:Real}(::Type{DateTime}, x::T) -> DateTime -Converts a number of type `T` to a DateTime. `x` should be the number of Rata Die milliseconds since epoch. -See `convert(Int64,dt::DateTime)` for inverse. -""" -Base.convert{R<:Real}(::Type{DateTime}, x::R) = DateTime(UTM(x)) -""" - convert{T<:Real}(::Type{Date}, x::T) -> Date -Converts a number of type `T` to a Date. `x` should be the number of Rata Die days since epoch. -See `convert(Int64,dt::Date)` for inverse. -""" -Base.convert{R<:Real}(::Type{Date}, x::R) = Date(UTD(x)) +Base.convert(::Type{DateTime},x::Millisecond) = DateTime(Dates.UTInstant(x)) # Converts Rata Die milliseconds to a DateTime +Base.convert(::Type{Millisecond},dt::DateTime) = Millisecond(value(dt)) # Converts DateTime to Rata Die milliseconds +Base.convert(::Type{Date},x::Day) = Date(Dates.UTInstant(x)) # Converts Rata Die days to a Date +Base.convert(::Type{Day},dt::Date) = Day(value(dt)) # Converts Date to Rata Die days ### External Conversions const UNIXEPOCH = value(DateTime(1970)) #Rata Die milliseconds for 1970-01-01T00:00:00 diff --git a/base/dates/periods.jl b/base/dates/periods.jl index 935a8363cfc45..07a8c5b9fddb0 100644 --- a/base/dates/periods.jl +++ b/base/dates/periods.jl @@ -37,16 +37,12 @@ for period in (:Year, :Month, :Week, :Day, :Hour, :Minute, :Second, :Millisecond """ $period(v) end end -# Now we're safe to define Period-Number conversions -# Anything an Int64 can convert to, a Period can convert to -Base.convert{T<:Number}(::Type{T},x::Period) = convert(T,value(x)) -Base.convert{T<:Period}(::Type{T},x::Real) = T(x) #Print/show/traits Base.string{P<:Period}(x::P) = string(value(x),_units(x)) Base.show(io::IO,x::Period) = print(io,string(x)) Base.zero{P<:Period}(::Union{Type{P},P}) = P(0) -Base.one{P<:Period}(::Union{Type{P},P}) = P(1) +Base.one{P<:Period}(::Union{Type{P},P}) = 1 # see #16116 Base.typemin{P<:Period}(::Type{P}) = P(typemin(Int64)) Base.typemax{P<:Period}(::Type{P}) = P(typemax(Int64)) @@ -54,13 +50,13 @@ Base.typemax{P<:Period}(::Type{P}) = P(typemax(Int64)) """ default(p::Period) -> Period -Returns a sensible "default" value for the input Period by returning `one(p)` for Year, -Month, and Day, and `zero(p)` for Hour, Minute, Second, and Millisecond. +Returns a sensible "default" value for the input Period by returning `T(1)` for Year, +Month, and Day, and `T(0)` for Hour, Minute, Second, and Millisecond. """ function default end -default{T<:DatePeriod}(p::Union{T,Type{T}}) = one(p) -default{T<:TimePeriod}(p::Union{T,Type{T}}) = zero(p) +default{T<:DatePeriod}(p::Union{T,Type{T}}) = T(1) +default{T<:TimePeriod}(p::Union{T,Type{T}}) = T(0) (-){P<:Period}(x::P) = P(-value(x)) Base.isless{P<:Period}(x::P,y::P) = isless(value(x),value(y)) diff --git a/base/dates/ranges.jl b/base/dates/ranges.jl index 17eed2054784d..92fb4868aaad3 100644 --- a/base/dates/ranges.jl +++ b/base/dates/ranges.jl @@ -4,12 +4,19 @@ # Override default step; otherwise it would be Millisecond(1) Base.colon{T<:DateTime}(start::T, stop::T) = StepRange(start, Day(1), stop) -Base.colon{T<:Time}(start::T, stop::T) = StepRange(start, Second(1), stop) +Base.colon{T<:Date}(start::T, stop::T) = StepRange(start, Day(1), stop) +Base.colon{T<:Time}(start::T, stop::T) = StepRange(start, Second(1), stop) + +Base.range(start::DateTime, len::Integer) = range(start, Day(1), len) +Base.range(start::Date, len::Integer) = range(start, Day(1), len) + +(::Type{StepRange{T,R}}){T<:Dates.DatePeriod,R<:Real}(start, step, stop) = + throw(ArgumentError("must specify step as a Period when constructing Dates ranges")) # Given a start and end date, how many steps/periods are in between -guess(a::DateTime,b::DateTime,c) = floor(Int64,(Int128(b) - Int128(a)) / toms(c)) -guess(a::Date,b::Date,c) = Int64(div(Int64(b - a), days(c))) -len(a::Time,b::Time,c) = Int64(div(Int64(b - a), tons(c))) +guess(a::DateTime,b::DateTime,c) = floor(Int64,(Int128(value(b)) - Int128(value(a)))/toms(c)) +guess(a::Date,b::Date,c) = Int64(div(value(b - a),days(c))) +len(a::Time,b::Time,c) = Int64(div(value(b - a), tons(c))) function len(a,b,c) lo, hi, st = min(a,b), max(a,b), abs(c) i = guess(a,b,c)-1 diff --git a/base/deprecated.jl b/base/deprecated.jl index 3f8a9f947a541..6151def6274ce 100644 --- a/base/deprecated.jl +++ b/base/deprecated.jl @@ -1773,4 +1773,17 @@ end) @deprecate EachLine(stream, ondone) EachLine(stream, ondone=ondone) +# These conversions should not be defined, see #19896 +@deprecate convert{T<:Number}(::Type{T}, x::Dates.Period) convert(T, Dates.value(x)) +@deprecate convert{T<:Dates.Period}(::Type{T}, x::Real) T(x) +@deprecate convert{R<:Real}(::Type{R}, x::Dates.DateTime) R(Dates.value(x)) +@deprecate convert{R<:Real}(::Type{R}, x::Dates.Date) R(Dates.value(x)) +@deprecate convert(::Type{Dates.DateTime}, x::Real) Dates.DateTime(Dates.Millisecond(x)) +@deprecate convert(::Type{Dates.Date}, x::Real) Dates.Date(Dates.Day(x)) + +function colon{T<:Dates.Period}(start::T, stop::T) + depwarn("$start:$stop is deprecated, use $start:$T(1):$stop instead.", :colon) + colon(start, T(1), stop) +end + # End deprecations scheduled for 0.6 diff --git a/test/dates/conversions.jl b/test/dates/conversions.jl index e35b8d84982c5..00c7538b5ca6b 100644 --- a/test/dates/conversions.jl +++ b/test/dates/conversions.jl @@ -61,11 +61,10 @@ let t = Dates.Period[Dates.Week(2), Dates.Day(14), Dates.Hour(14*24), Dates.Minu Pi = typeof(t[i]) for j = 1:length(t) @test t[i] == t[j] - @test Int(convert(Pi,t[j])) == Int(t[i]) end for j = i+1:length(t) Pj = typeof(t[j]) - tj1 = t[j] + one(Pj) + tj1 = t[j] + Pj(1) @test t[i] < tj1 @test_throws InexactError Pi(tj1) @test_throws InexactError Pj(Pi(typemax(Int64))) @@ -74,8 +73,7 @@ let t = Dates.Period[Dates.Week(2), Dates.Day(14), Dates.Hour(14*24), Dates.Minu end end @test Dates.Year(3) == Dates.Month(36) -@test Int(convert(Dates.Month, Dates.Year(3))) == 36 -@test Int(convert(Dates.Year, Dates.Month(36))) == 3 +@test_throws ErrorException Int(Dates.Month(36)) # eventually change to MethodError @test Dates.Year(3) < Dates.Month(37) @test_throws InexactError convert(Dates.Year, Dates.Month(37)) @test_throws InexactError Dates.Month(Dates.Year(typemax(Int64))) @@ -89,20 +87,20 @@ let dt = DateTime(1915,1,1,12) @test Dates.julian2datetime(julian) == dt end -# Conversions to/from numbers +# "Conversions" to/from numbers a = Dates.DateTime(2000) b = Dates.Date(2000) -@test convert(Real,b) == 730120 -@test convert(Float64,b) == 730120.0 -@test convert(Int32,b) == 730120 -@test convert(Real,a) == 63082368000000 -@test convert(Float64,a) == 63082368000000.0 -@test convert(Int64,a) == 63082368000000 -@test convert(DateTime,63082368000000) == a -@test convert(DateTime,63082368000000.0) == a -@test convert(Date,730120) == b -@test convert(Date,730120.0) == b -@test convert(Date,Int32(730120)) == b +@test Dates.value(b) == 730120 +@test Dates.value(a) == 63082368000000 +@test convert(Dates.DateTime, Dates.Millisecond(63082368000000)) == a +@test convert(Dates.Millisecond, a) == Dates.Millisecond(63082368000000) +@test Dates.DateTime(Dates.UTM(63082368000000)) == a +@test Dates.DateTime(Dates.UTM(63082368000000.0)) == a +@test convert(Dates.Date, Dates.Day(730120)) == b +@test convert(Dates.Day, b) == Dates.Day(730120) +@test Dates.Date(Dates.UTD(730120)) == b +@test Dates.Date(Dates.UTD(730120.0)) == b +@test Dates.Date(Dates.UTD(Int32(730120))) == b dt = Dates.DateTime(2000,1,1,23,59,59,50) t = Dates.Time(dt) @@ -111,4 +109,4 @@ t = Dates.Time(dt) @test Dates.second(t) == 59 @test Dates.millisecond(t) == 50 @test Dates.microsecond(t) == 0 -@test Dates.nanosecond(t) == 0 \ No newline at end of file +@test Dates.nanosecond(t) == 0 diff --git a/test/dates/periods.jl b/test/dates/periods.jl index 55b35de23e1e9..f0e36908848b5 100644 --- a/test/dates/periods.jl +++ b/test/dates/periods.jl @@ -61,23 +61,6 @@ ns = Dates.Nanosecond(1) @test Dates.Millisecond(ms) == ms @test Dates.Microsecond(us) == us @test Dates.Nanosecond(ns) == ns -@test typeof(Int8(y)) <: Int8 -@test typeof(UInt8(y)) <: UInt8 -@test typeof(Int16(y)) <: Int16 -@test typeof(UInt16(y)) <: UInt16 -@test typeof(Int32(y)) <: Int32 -@test typeof(UInt32(y)) <: UInt32 -@test typeof(Int64(y)) <: Int64 -@test typeof(UInt64(y)) <: UInt64 -@test typeof(Int128(y)) <: Int128 -@test typeof(UInt128(y)) <: UInt128 -@test typeof(convert(BigInt,y)) <: BigInt -@test typeof(convert(BigFloat,y)) <: BigFloat -@test typeof(convert(Complex,y)) <: Complex -@test typeof(convert(Rational,y)) <: Rational -@test typeof(Float16(y)) <: Float16 -@test typeof(Float32(y)) <: Float32 -@test typeof(Float64(y)) <: Float64 @test Dates.Year(convert(Int8,1)) == y @test Dates.Year(convert(UInt8,1)) == y @test Dates.Year(convert(Int16,1)) == y @@ -227,20 +210,6 @@ test = ((((((((dt + y) - m) + w) - d) + h) - mi) + s) - ms) @test zero(Dates.Second(10)) == Dates.Second(0) @test zero(Dates.Millisecond) == Dates.Millisecond(0) @test zero(Dates.Millisecond(10)) == Dates.Millisecond(0) -@test one(Dates.Year) == Dates.Year(1) -@test one(Dates.Year(10)) == Dates.Year(1) -@test one(Dates.Month) == Dates.Month(1) -@test one(Dates.Month(10)) == Dates.Month(1) -@test one(Dates.Day) == Dates.Day(1) -@test one(Dates.Day(10)) == Dates.Day(1) -@test one(Dates.Hour) == Dates.Hour(1) -@test one(Dates.Hour(10)) == Dates.Hour(1) -@test one(Dates.Minute) == Dates.Minute(1) -@test one(Dates.Minute(10)) == Dates.Minute(1) -@test one(Dates.Second) == Dates.Second(1) -@test one(Dates.Second(10)) == Dates.Second(1) -@test one(Dates.Millisecond) == Dates.Millisecond(1) -@test one(Dates.Millisecond(10)) == Dates.Millisecond(1) @test Dates.Year(-1) < Dates.Year(1) @test !(Dates.Year(-1) > Dates.Year(1)) @test Dates.Year(1) == Dates.Year(1) diff --git a/test/dates/ranges.jl b/test/dates/ranges.jl index 49a0f65f95bd6..cff8d771b7de5 100644 --- a/test/dates/ranges.jl +++ b/test/dates/ranges.jl @@ -478,10 +478,10 @@ let n=100000 return b end -@test length(Dates.Year(1):Dates.Year(10)) == 10 +@test length(Dates.Year(1):Dates.Year(1):Dates.Year(10)) == 10 @test length(Dates.Year(10):Dates.Year(-1):Dates.Year(1)) == 10 @test length(Dates.Year(10):Dates.Year(-2):Dates.Year(1)) == 5 -@test_throws OverflowError length(typemin(Dates.Year):typemax(Dates.Year)) +@test_throws OverflowError length(typemin(Dates.Year):Dates.Year(1):typemax(Dates.Year)) @test_throws MethodError Dates.Date(0):Dates.DateTime(2000) @test_throws MethodError Dates.Date(0):Dates.Year(10) @test length(range(Dates.Date(2000),366)) == 366