You can use an interval tree to store the time periods that you have cached - this will let you quickly retrieve the cached time periods that overlap with a user's query. You can then use this time period library to determine what queries need to be submitted to the web service in order to fill the user's query by taking the differences between the queried interval and the cached intervals.
Once you fill the user's query then you should reorganize the interval tree to merge any overlapping or abutting time intervals (e.g. if you had previously cached the intervals [2, 6] and [12, 16] and the user queries [4, 14], then you should submit a [6, 12] query to the web service, remove the [2, 6] and [12, 16] intervals from the interval tree, and add a [2, 16] interval in their place). You may also want to avoid caching small intervals if you want to avoid making too many queries to the web service (e.g. if the user wants [1, 2] and you've cached [1, 1.1], [1.3, 1.4], [1.5, 1.6], [1.8, 1.9], then you'll be making 4 queries to fill the user's query), either by discarding small intervals or by always retrieving a minimal interval so that none of your cached intervals is "too small" (e.g. if the user queries [1.4, 1.5] you would submit a [1, 2] query to the web service).