# Cannot use a Dates.Hour and Dates.Month as keys in the same Dict

**URL:** <https://discourse.julialang.org/t/cannot-use-a-dates-hour-and-dates-month-as-keys-in-the-same-dict/10845>\
**Category:** General Usage\
**Created:** [May 11, 2018, 5:35pm UTC](https://discourse.julialang.org/t/cannot-use-a-dates-hour-and-dates-month-as-keys-in-the-same-dict/10845 "2018-05-11T17:35:57Z")\
**Posts on this page:** 10\
**Page:** 1

<div class="post-metadata">

**Author:** ![bluesmoon](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/bluesmoon/32/327_2.png) [@bluesmoon](https://discourse.julialang.org/u/bluesmoon)\
**Post date:** [May 11, 2018, 5:35pm UTC](https://discourse.julialang.org/t/cannot-use-a-dates-hour-and-dates-month-as-keys-in-the-same-dict/10845/1 "2018-05-11T17:35:57Z")

</div>

It appears that I cannot have a Dict with `Dates.Hour(1)` and `Dates.Month(1)` as keys. I can have absolutely any other type/value as a key in this Dict, but I cannot put these two keys together in the same Dict.

It does not matter what order they are added in, the second one will throw an exception about the missing `==` method, but I don’t understand that because both of these are subtypes of `Base.Period` and we have `==(::Base.Dates.Period, ::Base.Dates.Period)` defined, so why wouldn’t the compiler use that?

What’s even weirder, is I can use `Dates.Hour(2)` and `Dates.Hour(0)`, but not `Dates.Hour(1)`, and the same for `Dates.Month`

```julia
julia> DATEPART_DISPLAY = Dict{Dates.Period, AbstractString}()
Dict{Base.Dates.Period,AbstractString} with 0 entries

julia> DATEPART_DISPLAY[Dates.Month(1)] = "%b %Y"
"%b %Y"

julia> DATEPART_DISPLAY[Dates.Week(1)] = "%b %d %Y"
"%b %d %Y"

julia> DATEPART_DISPLAY[Dates.Hour(1)] = "%b %d %Y, %H:%M"
ERROR: MethodError: no method matching ==(::Base.Dates.Hour, ::Base.Dates.Month)
Closest candidates are:
  ==(::Union{Base.Dates.Day, Base.Dates.Hour, Base.Dates.Microsecond, Base.Dates.Millisecond, Base.Dates.Minute, Base.Dates.Nanosecond, Base.Dates.Second, Base.Dates.Week}, ::Union{Base.Dates.Month, Base.Dates.Year}) at dates/periods.jl:443
  ==(::Base.Dates.Period, ::Base.Dates.Period) at dates/periods.jl:63
  ==(::Any, ::Any) at operators.jl:52
  ...
Stacktrace:
 [1] ==(::Base.Dates.Hour, ::Base.Dates.Month) at ./dates/periods.jl:443
 [2] ht_keyindex2(::Dict{Base.Dates.Period,AbstractString}, ::Base.Dates.Hour) at ./dict.jl:366
 [3] setindex!(::Dict{Base.Dates.Period,AbstractString}, ::String, ::Base.Dates.Hour) at ./dict.jl:421

julia> DATEPART_DISPLAY[Dates.Minute(1)] = "%b %d %Y, %H:%M"
"%b %d %Y, %H:%M"

julia> DATEPART_DISPLAY[Dates.Second(1)] = "%b %d %Y, %H:%M:%S"
"%b %d %Y, %H:%M:%S"

julia> DATEPART_DISPLAY[Dates.Year(1)] = "%Y"
"%Y"

```

```julia
julia> versioninfo()
Julia Version 0.6.3-pre.2
Commit c011bb7 (2018-05-08 17:03 UTC)
DEBUG build
Platform Info:
  OS: Linux (x86_64-linux-gnu)
  CPU: Intel(R) Core(TM) i7-4770HQ CPU @ 2.20GHz
  WORD_SIZE: 64
  BLAS: libopenblas (USE64BITINT DYNAMIC_ARCH NO_AFFINITY Haswell)
  LAPACK: libopenblas64_
  LIBM: libopenlibm
  LLVM: libLLVM-3.9.1 (ORCJIT, haswell)

```

---

<div class="post-metadata">

**Author:** ![ExpandingMan](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/expandingman/32/866_2.png) [@ExpandingMan](https://discourse.julialang.org/u/ExpandingMan)\
**Post date:** [May 11, 2018, 6:02pm UTC](https://discourse.julialang.org/t/cannot-use-a-dates-hour-and-dates-month-as-keys-in-the-same-dict/10845/2 "2018-05-11T18:02:41Z")

</div>

I tested this on 0.7 quick. I don’t get an error when assigning elements to the dict, however I do get

```julia
julia> Hour(1) == Month(1)
ERROR: MethodError: no method matching ==(::Hour, ::Month)
Closest candidates are:
  ==(::Union{Day, Hour, Microsecond, Millisecond, Minute, Nanosecond, Second, Week}, ::Union{Month, Year}) at /buildworker/worker/package_linux64/build/usr/share/julia/stdlib/v0.7/Dates/src/periods.jl:446
  ==(::Period, ::Period) at /buildworker/worker/package_linux64/build/usr/share/julia/stdlib/v0.7/Dates/src/periods.jl:63
  ==(::Any, ::Any) at operators.jl:81

```

This seems like a bug to me, although I don’t understand why in the world it’s happening. It should match all 3 of the methods listed. Perhaps this is some sort of weird method ambiguity bug?

---

<div class="post-metadata">

**Author:** ![bluesmoon](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/bluesmoon/32/327_2.png) [@bluesmoon](https://discourse.julialang.org/u/bluesmoon)\
**Post date:** [May 11, 2018, 6:09pm UTC](https://discourse.julialang.org/t/cannot-use-a-dates-hour-and-dates-month-as-keys-in-the-same-dict/10845/3 "2018-05-11T18:09:09Z")

</div>

yeah, for the `==` check I get the error even with `Hour(2)`, but that works in the Dict

---

<div class="post-metadata">

**Author:** ![ExpandingMan](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/expandingman/32/866_2.png) [@ExpandingMan](https://discourse.julialang.org/u/ExpandingMan)\
**Post date:** [May 11, 2018, 6:15pm UTC](https://discourse.julialang.org/t/cannot-use-a-dates-hour-and-dates-month-as-keys-in-the-same-dict/10845/4 "2018-05-11T18:15:47Z")

</div>

Ah, I think I’ve found what’s going on. If you look [here](https://github.com/JuliaLang/julia/blob/master/stdlib/Dates/src/periods.jl#L446) you will see that this method has been explicitly defined to throw a `MethodError`. Why? Well, it’s because `Month` and `Year` aren’t real time intervals.

That’s right, `Month` and `Year` don’t represent any fixed period of time. Yes, DateTime is one of the most macabre, horrific things ever created by the low animal minds of confused humans who couldn’t handle the fact that the planet that they live on and its satellite have rotational and revolutionary periods that are not in resonance with eachother. This isn’t a Julia bug, this is a bug in human society. I loathe that I ever have to use these godawful things.

Anyway, enough pontificating. This isn’t a bug, however, it would be nice if they chose a more informative error to throw here. It might even be worth filing an issue over. I’m not quite sure why the `Dict` is checking for equality, it should just be hashing the arguments. I guess it still does this for collision checking, but like I said, it doesn’t seem to happen in 0.7, for whatever reason.

---

<div class="post-metadata">

**Author:** ![bluesmoon](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/bluesmoon/32/327_2.png) [@bluesmoon](https://discourse.julialang.org/u/bluesmoon)\
**Post date:** [May 11, 2018, 6:23pm UTC](https://discourse.julialang.org/t/cannot-use-a-dates-hour-and-dates-month-as-keys-in-the-same-dict/10845/5 "2018-05-11T18:23:52Z")

</div>

I can live with the comparison being indeterminate. I don’t need to compare these intervals. All I need is to put them in a Dict. Well, its `Minute(60)` for now.

---

<div class="post-metadata">

**Author:** ![simonbyrne](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/simonbyrne/32/19_2.png) [@simonbyrne](https://discourse.julialang.org/u/simonbyrne)\
**Post date:** [May 11, 2018, 6:24pm UTC](https://discourse.julialang.org/t/cannot-use-a-dates-hour-and-dates-month-as-keys-in-the-same-dict/10845/6 "2018-05-11T18:24:50Z")

</div>

Please open an issue: this is definitely a bug.

---

<div class="post-metadata">

**Author:** ![ExpandingMan](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/expandingman/32/866_2.png) [@ExpandingMan](https://discourse.julialang.org/u/ExpandingMan)\
**Post date:** [May 11, 2018, 6:25pm UTC](https://discourse.julialang.org/t/cannot-use-a-dates-hour-and-dates-month-as-keys-in-the-same-dict/10845/7 "2018-05-11T18:25:57Z")

</div>

Is it though? It might be a bug in `Dict`, which is fixed on 0.7, but `==` fails on these types for a very good reason.

I just compared the `Dict` `setindex!` code in 0.6 and 0.7 and they look the same, so I’m still not sure what’s going on.

---

<div class="post-metadata">

**Author:** ![bluesmoon](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/bluesmoon/32/327_2.png) [@bluesmoon](https://discourse.julialang.org/u/bluesmoon)\
**Post date:** [May 11, 2018, 6:47pm UTC](https://discourse.julialang.org/t/cannot-use-a-dates-hour-and-dates-month-as-keys-in-the-same-dict/10845/8 "2018-05-11T18:47:42Z")

</div>

Opened [https://github.com/JuliaLang/julia/issues/27076](https://github.com/JuliaLang/julia/issues/27076)

---

<div class="post-metadata">

**Author:** ![foobar\_lv2](https://avatars.discourse-cdn.com/v4/letter/f/ee59a6/32.png) [@foobar\_lv2](https://discourse.julialang.org/u/foobar_lv2)\
**Post date:** [May 19, 2018, 2:53pm UTC](https://discourse.julialang.org/t/cannot-use-a-dates-hour-and-dates-month-as-keys-in-the-same-dict/10845/9 "2018-05-19T14:53:06Z")

</div>

You only trigger the bad comparison if you have a (truncated) hash collision. Hence, hard to reproduce on different julia versions.

```julia
julia> using Dates #skip this on 0.6

julia> DATEPART_DISPLAY = Dict{Dates.Period, AbstractString}()
Dict{Period,AbstractString} with 0 entries

julia> for i=1:1000 DATEPART_DISPLAY[Dates.Hour(rand(Int))] = "" end

julia> for i=1:1000 DATEPART_DISPLAY[Dates.Month(rand(Int))] = "" end
ERROR: MethodError: no method matching ==(::Month, ::Hour)

```

---

<div class="post-metadata">

**Author:** ![jlapeyre](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/jlapeyre/32/4514_2.png) [@jlapeyre](https://discourse.julialang.org/u/jlapeyre)\
**Post date:** [May 19, 2018, 7:36pm UTC](https://discourse.julialang.org/t/cannot-use-a-dates-hour-and-dates-month-as-keys-in-the-same-dict/10845/10 "2018-05-19T19:36:40Z")

</div>

```julia
julia> Dates.Hour <: Dates.Period
true

julia> Dates.Week <: Dates.Period
true

julia> Dates.Month <: Dates.Period
true

julia> Dates.Hour(1) == Dates.Week(1)
false

julia> Dates.Hour(1) == Dates.Month(1)
ERROR: MethodError: no method matching ==(::Base.Dates.Hour, ::Base.Dates.Month)
Closest candidates are:

```

If you look at the code in `periods.jl` its clear the intent is to be able to compare any subtypes of `Period`. I find this is broken on v0.6.2 and also on a few week old build of v0.7
