FlexiJoins.jl is the most general package for joining datasets, to my knowledge. It does efficient joins by predicates such as the one you need, and also supports DataFrames
merge A and B based on (id = id, date1 < date < date2)
using FlexiJoins, IntervalSets
innerjoin((A, B), by_key(:id) & by_pred(:date, ∈, x -> x.date1..x.date2))