Reputation: 46490
I need to determine the duration between now and the next occurrance of a local time. Here's what I've got:
Duration GetDuration(IClock clock, LocalTime time, DateTimeZone zone)
{
// get the current time in this zone
var now = clock.Now.InZone(zone);
// find the time in our zone today
var timeToday = zone.AtLeniently(now.Date + time);
// find the time in our zone tomorrow
var timeTomorrow = zone.AtLeniently(now.Date.PlusDays(1) + time);
// get the next occurrance of that time
var next = new[]{timeToday, timeTomorrow}.Where(x => x > now).Min();
// calculate the duration between now and the next occurance of that time
var duration = next.ToInstant() - now.ToInstant();
Debug.Assert(duration > Duration.Zero);
return duration;
}
And a test to get the duration between now and the next instant of 5PM eastern time:
var duration = GetDuration(
SystemClock.Instance,
new LocalTime(17,00),
DateTimeZoneProviders.Tzdb["US/Eastern"]);
My question is, since I'm new to NodaTime, am I taking any unnecessary steps or missing any shortcuts?
Upvotes: 3
Views: 414
Reputation: 3883
The most easy way is like this:
LocalDate now = LocalDate.now();
LocalDate now2 = now.plusDays(4);
ChronoUnit.DAYS.between(now, now2);
Upvotes: 0
Reputation: 1504092
This code is a bit more long-winded than it needs to be - I'd do most of the work in the "local" context, and only convert back to the time zone when you know the LocalDateTime
you want to map.
var now = clock.Now.InZone(zone);
// Change this to <= time if you want it to be a "strictly next".
var nextDate = now.TimeOfDay < time ? now.Date : now.Date.PlusDays(1);
return zone.AtLeniently(nextDate + time).ToInstant() - now.ToInstant();
AtLeniently
will always return a value which is no earlier than the given LocalDateTime
(it returns the later of two ambiguous options, and the start of the interval after a skipped time), so you don't need to worry about DST transitions.
As an aside, feedback about whether the ToInstant()
calls in the last line are annoying would be useful. I'd at least consider adding a Duration operator-(ZonedDateTime, ZonedDateTime)
to 2.0.
Upvotes: 3