private static DateTimeOffset GetNextCycleTargetTime(DateTimeOffset periodStart) { // Next tick: (current time rounded down to MINUTE start) + (1 minute) + (small sub-minute offset). // The strategy here is to always "tick" at the same offset within a minute. // Due to drift and inprecize timing this may conflict with the aggregation being exactly a minute. // In such cases we err on the side of keeping the same offset. // This will tend to straighten out the inmterval and to yield consistent timestamps. const int targetOffsetFromRebasedCurrentTimeInSecs = 60 + 1; const double minPeriodInSecs = 20.0 + 1.0; DateTimeOffset target = Util.RoundDownToMinute(periodStart).AddSeconds(targetOffsetFromRebasedCurrentTimeInSecs); // If this results in the next period being unreasonably short, we extend that period by 1 minute, // resulting in a total period that is somewhat longer than a minute. TimeSpan waitPeriod = target - periodStart; if (waitPeriod.TotalSeconds < minPeriodInSecs) { target = target.AddMinutes(1); } return(target); }