public void DepositCheque(Guid chequeId, double amount, IClock clock, CorrelatedMessage source) { if (amount <= 0) { throw new InvalidOperationException("Cheque's amount must be strictly positive"); } var depositTime = clock.GetCurrentInstant(); Instant clearanceTime = depositTime; switch (clearanceTime.InUtc().DayOfWeek) { case IsoDayOfWeek.Saturday: clearanceTime.Plus(Duration.FromDays(2)); break; case IsoDayOfWeek.Sunday: clearanceTime.Plus(Duration.FromDays(1)); break; } Raise(new ChequeDeposited(source) { AccountId = Id, ChequeId = chequeId, Amount = amount, DepositTime = depositTime, ClearanceTime = clearanceTime }); }
public Instant AddDuration(Instant startInstant, string duration, int numberOfDurations) { return(duration switch { "PT1H" => startInstant.Plus(Duration.FromHours(numberOfDurations)), "PT15M" => startInstant.Plus(Duration.FromMinutes(15 * numberOfDurations)), "P1D" => AddDayDuration(startInstant, numberOfDurations), "P1M" => AddMonthDuration(startInstant, numberOfDurations), _ => throw new ArgumentException($"Unknown time resolution: {duration}"), });
public async Task WriteNewScheduleTargets() { // Decisions about whether the once-daily run target is near enough: if (await WasLastRunToday()) { return; } // This will be an HHmm value such as 1030 or 2200; SchedulerQueue only invokes this // grain at 15-minute intervals, so quit unless we're near or past the run-at time. var paddedUtc = todayUtc.PlusMinutes(5); var paddedTime = paddedUtc.TimeOfDay; var runTargetUtc = await configCache.GetValue(ConstConfigKeys.ScheduleWriterRunTargetUtc); var(runHour, runMinute) = DateTimeAnalysis.GetHourMinute(runTargetUtc); if (paddedUtc.Date == todayUtc.Date && (paddedTime.Hour < runHour || (paddedTime.Hour == runHour && paddedTime.Minute < runMinute))) { return; } // Decision made: yes, write the next day's schedule records. logger.LogInformation($"WriteNewScheduleTargets"); var jobs = await scheduleRepository.GetJobsWithScheduleSettings(); if (jobs.Count == 0) { return; } foreach (var job in jobs) { try { var planner = new TargetPlanner(job, today.Plus(Duration.FromDays(1)), logger); var newSchedules = planner.GetSchedules(); if (newSchedules.Count > 0) { await InsertScheduleRows(newSchedules); } newSchedules = null; } catch { } } await configRepository.UpdateConfig(ConstConfigKeys.ScheduleWriterLastRunDateUtc, InstantPattern.General.Format(today)); }
/// <summary> /// Returns the given instant adjusted one year backward taking into account leap years and other /// adjustments like day of week. /// </summary> /// <param name="instant">The <see cref="Instant"/> lower bound for the next trasnition.</param> /// <param name="standardOffset">The <see cref="Offset"/> standard offset.</param> /// <param name="previousSavings">The <see cref="Offset"/> savings adjustment at the given Instant.</param> /// <returns>The previous transition, or null if there is no previous transition.</returns> internal Transition?Previous(Instant instant, Offset standardOffset, Offset previousSavings) { CalendarSystem calendar = CalendarSystem.Iso; Offset wallOffset = standardOffset + previousSavings; int year = instant == Instant.MaxValue ? Int32.MaxValue : calendar.GetYear(instant.Plus(wallOffset)); if (year > toYear) { // First pull instant back to the start of the year after toYear instant = calendar.GetLocalInstant(toYear + 1, 1, 1, 0, 0).Minus(wallOffset); } Instant previous = yearOffset.Previous(instant, standardOffset, previousSavings); if (previous <= instant) { year = calendar.GetYear(previous.Plus(wallOffset)); if (year < fromYear) { return(null); } } return(new Transition(previous, wallOffset, standardOffset + Savings)); }
public ActionResult <NodaTimeModel> GetModel() { var dateTimeZone = DateTimeZoneProviders.Tzdb.GetSystemDefault(); Instant instant = Instant.FromDateTimeUtc(DateTime.UtcNow); ZonedDateTime zonedDateTime = instant.InZone(dateTimeZone); NodaTimeModel nodaTimeModel = new NodaTimeModel { DateTimeZone = DateTimeZone.Utc, Instant = instant, DateTime = DateTime.UtcNow, Interval = new Interval(instant, instant.Plus(Duration.FromHours(1))), DateInterval = new DateInterval(zonedDateTime.Date, zonedDateTime.Date.PlusDays(1)), Period = Period.FromHours(1), ZonedDateTime = zonedDateTime, OffsetDateTime = instant.WithOffset(Offset.FromHours(1)), LocalDate = zonedDateTime.Date, LocalTime = zonedDateTime.TimeOfDay, LocalDateTime = zonedDateTime.LocalDateTime, Offset = zonedDateTime.Offset, Duration = Duration.FromHours(1), OffsetDate = new OffsetDate(zonedDateTime.Date, zonedDateTime.Offset), OffsetTime = new OffsetTime(zonedDateTime.TimeOfDay, zonedDateTime.Offset), }; return(nodaTimeModel); }
public async Task UpdateExistingSharedState_SetsUpdatedTime() { Instant createdInstant = SystemClock.Instance.GetCurrentInstant(); //Arrange FakeClock fakeClock = new FakeClock(createdInstant); SharedStateController controller = new SharedStateController(new TestDatabaseHandler <SharedState.SharedState>(), fakeClock); string anchorSetId = "anchorSetId"; string spaceid = "spaceId"; SharedStateDto sharedState = new SharedStateDto(new SharedState.SharedState() { Id = anchorSetId, CurrentSelectedSpace = spaceid }); //Act await controller.UpdateSharedState(anchorSetId, sharedState); fakeClock.AdvanceMinutes(1); await controller.UpdateSharedState(anchorSetId, sharedState); //Assert SharedState.SharedState fetchedState = await controller.GetSharedState(anchorSetId); fetchedState.CreatedAt.Should().Be(createdInstant); fetchedState.UpdatedAt.Should().Be(createdInstant.Plus(Duration.FromMinutes(1))); }
public async void GeneratedAccessTokenContainsCorrectContentAndValidatesAgainstSignature(int tokenOffset1, string user) { IdentityModelEventSource.ShowPII = true; var service = new JwtService( _refreshTokenRepository, _testSecret1, tokenOffset1, _testSecret2, -1) { Clock = _fromUnixStartOneMinuteInterval }; var token = service.GenerateAccessToken(await _userService.GetClaimsForUser(user)); var handler = new JwtSecurityTokenHandler(); handler.ValidateToken(token, _accessTokenValidationParameters, out var validToken); var jwt = validToken as JwtSecurityToken; Assert.NotNull(jwt); Assert.True(Instant.FromDateTimeUtc(jwt.ValidTo) .Equals(_unixStart.Plus(Duration.FromMinutes(tokenOffset1)))); Assert.Equal(user, jwt.Subject); Assert.Equal("testrole", jwt.Claims .Where(c => c.Type == "role") .Select(c => c.Value).FirstOrDefault()); }
public ViewModel() { List <Appointment> appointments = new List <Appointment>(); int days = 5 * 7; int appointmentsPerDay = 3; Random random = new Random(); Instant now = SystemClock.Instance.GetCurrentInstant(); for (int i = 0; i < days; i++) { Instant appointmentStart = now; for (int j = 0; j < random.Next() % 10; j++) { var appointmentEnd = appointmentStart.Plus(Duration.FromMinutes(15)); appointments.Add(new Appointment(i, new Interval(appointmentStart, appointmentEnd), false, Guid.NewGuid().ToString())); appointmentStart = appointmentEnd.Plus(Duration.FromMinutes(15)); } now = now.Plus(Duration.FromDays(1)); } Appointments = appointments; }
public void Can_Write_And_Read_Instant_Stored_As_Int64() { Instant startInstant = TestClock.Now; var testEvent = new InstantTestEntity { Description = "Can_Write_And_Read_Instant_Stored_As_Int64", StartInstant = startInstant, FinishInstant = startInstant.Plus(Duration.FromHours(1)) }; using (ISession session = SessionFactory.OpenSession()) using (ITransaction transaction = session.BeginTransaction()) { session.Save(testEvent); transaction.Commit(); } InstantTestEntity retrievedEvent; using (ISession session = SessionFactory.OpenSession()) using (ITransaction transaction = session.BeginTransaction()) { retrievedEvent = session.Get <InstantTestEntity>(testEvent.Id); transaction.Commit(); } Assert.That(retrievedEvent.StartInstant, Is.EqualTo(testEvent.StartInstant)); Assert.That(retrievedEvent.FinishInstant, Is.EqualTo(testEvent.FinishInstant)); Assert.That(retrievedEvent, Is.EqualTo(testEvent)); }
/// <summary> /// Returns the given instant adjusted one year forward taking into account leap years and other /// adjustments like day of week. /// </summary> /// <remarks> /// If the given instant is before the starting year, the year of the given instant is /// adjusted to the beginning of the starting year. The first transition after the /// adjusted instant is determined. If the next adjustment is after the ending year, this /// method returns null; otherwise the next transition is returned. /// </remarks> /// <param name="instant">The <see cref="Instant"/> lower bound for the next transition.</param> /// <param name="standardOffset">The <see cref="Offset"/> standard offset.</param> /// <param name="previousSavings">The <see cref="Offset"/> savings adjustment at the given Instant.</param> /// <returns>The next transition, or null if there is no next transition.</returns> internal Transition?Next(Instant instant, Offset standardOffset, Offset previousSavings) { CalendarSystem calendar = CalendarSystem.Iso; Offset wallOffset = standardOffset + previousSavings; int year = instant == Instant.MinValue ? Int32.MinValue : calendar.GetYear(instant.Plus(wallOffset)); if (year < fromYear) { // First advance instant to start of from year. instant = calendar.GetLocalInstant(fromYear, 1, 1, 0, 0).Minus(wallOffset); // Back off one tick to account for next recurrence being exactly at the beginning // of the year. instant = instant - Duration.Epsilon; } Instant next = yearOffset.Next(instant, standardOffset, previousSavings); if (next >= instant) { year = calendar.GetYear(next.Plus(wallOffset)); if (year > toYear) { return(null); } } return(new Transition(next, wallOffset, standardOffset + Savings)); }
public async Task Should_set_next_attempt_based_on_num_calls(int calls, int minutes, RuleResult result, RuleJobResult jobResult) { var actionData = new JObject(); var actionName = "MyAction"; var @event = CreateEvent(calls, actionName, actionData); var requestElapsed = TimeSpan.FromMinutes(1); var requestDump = "Dump"; A.CallTo(() => ruleService.InvokeAsync(@event.Job.ActionName, @event.Job.ActionData)) .Returns((requestDump, result, requestElapsed)); Instant?nextCall = null; if (minutes > 0) { nextCall = now.Plus(Duration.FromMinutes(minutes)); } await sut.HandleAsync(@event); A.CallTo(() => ruleEventRepository.MarkSentAsync(@event.Id, requestDump, result, jobResult, requestElapsed, nextCall)) .MustHaveHappened(); }
public void Should_set_next_attempt_based_on_num_calls(int calls, int minutes, RuleResult result, RuleJobResult jobResult) { var actionData = new RuleJobData(); var actionName = "MyAction"; var @event = CreateEvent(calls, actionName, actionData); var requestElapsed = TimeSpan.FromMinutes(1); var requestDump = "Dump"; SetupSender(@event, requestDump, result, requestElapsed); SetupPendingEvents(@event); var sut = new RuleDequeuer( ruleService, ruleEventRepository, log, clock); sut.Next(); sut.Dispose(); Instant?nextCall = null; if (minutes > 0) { nextCall = now.Plus(Duration.FromMinutes(minutes)); } VerifyRepositories(@event, requestDump, result, jobResult, requestElapsed, nextCall); }
/// <summary> /// Add days /// </summary> /// <param name="i"></param> /// <param name="days"></param> /// <returns></returns> /// <exception cref="ArgumentNullException"></exception> public static Instant PlusDays(this Instant i, double days) { if (i == null) { throw new ArgumentNullException(nameof(i)); } return(i.Plus(days.DurationDays())); }
/// <summary> /// Add milliseconds /// </summary> /// <param name="i"></param> /// <param name="milliseconds"></param> /// <returns></returns> /// <exception cref="ArgumentNullException"></exception> public static Instant PlusMilliseconds(this Instant i, long milliseconds) { if (i == null) { throw new ArgumentNullException(nameof(i)); } return(i.Plus(milliseconds.DurationMilliseconds())); }
/// <summary> /// Add DateTimeSpan /// </summary> /// <param name="i"></param> /// <param name="ts"></param> /// <returns></returns> /// <exception cref="ArgumentNullException"></exception> public static Instant PlusTimeSpan(this Instant i, DateTimeSpan ts) { if (i == null) { throw new ArgumentNullException(nameof(i)); } return(i.Plus(ts.AsDuration())); }
/// <summary> /// Add seconds /// </summary> /// <param name="i"></param> /// <param name="seconds"></param> /// <returns></returns> /// <exception cref="ArgumentNullException"></exception> public static Instant PlusSeconds(this Instant i, double seconds) { if (i == null) { throw new ArgumentNullException(nameof(i)); } return(i.Plus(seconds.DurationSeconds())); }
/// <summary> /// Add hours /// </summary> /// <param name="i"></param> /// <param name="hours"></param> /// <returns></returns> /// <exception cref="ArgumentNullException"></exception> public static Instant PlusHours(this Instant i, double hours) { if (i == null) { throw new ArgumentNullException(nameof(i)); } return(i.Plus(hours.DurationHours())); }
/// <summary> /// Add Minutes /// </summary> /// <param name="i"></param> /// <param name="minutes"></param> /// <returns></returns> /// <exception cref="ArgumentNullException"></exception> public static Instant PlusMinutes(this Instant i, double minutes) { if (i == null) { throw new ArgumentNullException(nameof(i)); } return(i.Plus(minutes.DurationMinutes())); }
/// <summary> /// Returns the given instant adjusted one year backward taking into account leap years and other /// adjustments like day of week. /// </summary> /// <param name="instant">The instant to adjust.</param> /// <param name="standardOffset">The standard offset.</param> /// <param name="savings">The daylight savings adjustment.</param> /// <returns>The adjusted <see cref="LocalInstant"/>.</returns> internal Instant Previous(Instant instant, Offset standardOffset, Offset savings) { Offset offset = GetOffset(standardOffset, savings); LocalInstant local = instant.Plus(offset); int year = GetEligibleYear(CalendarSystem.Iso.GetYear(local), -1); Instant transitionSameYear = MakeInstant(year, standardOffset, savings); return(transitionSameYear < instant ? transitionSameYear : MakeInstant(GetEligibleYear(year - 1, -1), standardOffset, savings)); }
public void Contains_LocalInstant_WholeOfTime() { ZoneInterval interval = new ZoneInterval("All Time", Instant.MinValue, Instant.MaxValue, Offset.FromHours(9), Offset.FromHours(1)); Assert.IsTrue(interval.Contains(SampleStart.Plus(Offset.Zero))); Assert.IsTrue(interval.Contains(LocalInstant.MinValue)); Assert.IsTrue(interval.Contains(LocalInstant.MaxValue)); }
public async Task Should_schedule_With_due_time() { var time = now.Plus(Duration.FromSeconds(1000)); await _.Store.EnqueueScheduledAsync("1", 1, time); var notDequeued = await _.Store.DequeueAsync(now); Assert.Null(notDequeued); var dequeued = await _.Store.DequeueAsync(time); Assert.NotNull(dequeued); var dequeuedAgain = await _.Store.DequeueAsync(time); Assert.Null(dequeuedAgain); }
private static DataScheduledTask CreateScheduledTask(Instant currentInstant, ScheduledTaskType scheduledTaskType, bool isDue) { var nextRunTimeOffset = isDue ? -1.Seconds() : 1.Seconds(); return(new DataScheduledTask { NextRunTime = currentInstant.Plus(nextRunTimeOffset), ScheduledTaskType = scheduledTaskType }); }
public void Can_Query_By_LessThan_Instant_Stored_As_Int64() { Instant startInstant = TestClock.Now.Minus(Duration.FromHours(24)); Instant finishInstant = startInstant.Plus(Duration.FromHours(1)); var testEvent = new InstantTestEntity { Description = "Can_Query_By_LessThan_Instant_Stored_As_Int64", StartInstant = startInstant, FinishInstant = finishInstant }; using (ISession session = SessionFactory.OpenSession()) using (ITransaction transaction = session.BeginTransaction()) { session.Save(testEvent); transaction.Commit(); } Instant beforeInstant = startInstant.Plus(Duration.FromSeconds(1)); using (ISession session = SessionFactory.OpenSession()) using (ITransaction transaction = session.BeginTransaction()) { var query = session.Query <InstantTestEntity>() .Where(x => x.Id == testEvent.Id && x.StartInstant < beforeInstant); var retrievedEvent = query.SingleOrDefault(); transaction.Commit(); Assert.That(testEvent, Is.Not.Null); Assert.That(testEvent, Is.EqualTo(retrievedEvent)); } using (ISession session = SessionFactory.OpenSession()) using (ITransaction transaction = session.BeginTransaction()) { var query = session.Query <InstantTestEntity>() .Where(x => x.Id == testEvent.Id && x.StartInstant < beforeInstant && x.FinishInstant <= finishInstant); var retrievedEvent = query.SingleOrDefault(); transaction.Commit(); Assert.That(testEvent, Is.Not.Null); Assert.That(testEvent, Is.EqualTo(retrievedEvent)); } }
public async Task Should_update_repositories_on_successful_requests() { var appId = new NamedId <Guid>(Guid.NewGuid(), "my-app"); var schemaId = new NamedId <Guid>(Guid.NewGuid(), "my-schema"); var @event = Envelope.Create(new ContentCreated { AppId = appId, SchemaId = schemaId }); var webhook1 = CreateWebhook(1); var webhook2 = CreateWebhook(2); A.CallTo(() => webhookRepository.QueryUrlsBySchemaAsync(appId.Id, schemaId.Id)) .Returns(Task.FromResult <IReadOnlyList <ISchemaWebhookUrlEntity> >(new List <ISchemaWebhookUrlEntity> { webhook1, webhook2 })); await sut.On(@event); A.CallTo(() => webhookEventRepository.EnqueueAsync( A <WebhookJob> .That.Matches(webhookJob => !string.IsNullOrWhiteSpace(webhookJob.RequestSignature) && !string.IsNullOrWhiteSpace(webhookJob.RequestBody) && webhookJob.Id != Guid.Empty && webhookJob.Expires == now.Plus(Duration.FromDays(2)) && webhookJob.AppId == appId.Id && webhookJob.EventName == "MySchemaCreatedEvent" && webhookJob.RequestUrl == webhook1.Url && webhookJob.WebhookId == webhook1.Id), now)).MustHaveHappened(); A.CallTo(() => webhookEventRepository.EnqueueAsync( A <WebhookJob> .That.Matches(webhookJob => !string.IsNullOrWhiteSpace(webhookJob.RequestSignature) && !string.IsNullOrWhiteSpace(webhookJob.RequestBody) && webhookJob.Id != Guid.Empty && webhookJob.Expires == now.Plus(Duration.FromDays(2)) && webhookJob.AppId == appId.Id && webhookJob.EventName == "MySchemaCreatedEvent" && webhookJob.RequestUrl == webhook2.Url && webhookJob.WebhookId == webhook2.Id), now)).MustHaveHappened(); }
public static IEnumerable <Instant> HourlyUtc(ZonedDateTimeRange range) { Instant c = range.Start.ToInstant(); Instant e = range.End.ToInstant(); while (c < e) { yield return(c); c = c.Plus(Duration.FromHours(1)); } }
public async Task Should_send_again_after_3_days() { var user = SetupUser("1", "*****@*****.**"); var notification = new UsageNotification { AppName = "my-app", Usage = 1000, UsageLimit = 3000, Users = new[] { "1" } }; await sut.NotifyAsync(notification); time = time.Plus(Duration.FromDays(3)); await sut.NotifyAsync(notification); A.CallTo(() => notificationSender.SendUsageAsync(user !, "my-app", 1000, 3000)) .MustHaveHappenedTwiceExactly(); }
public static Duration GetPoTime( int offsetMinutes, ArenaType arenaType, Instant?utcNow = null) { Instant other = utcNow.HasValue ? utcNow.Value : SystemClock.Instance.GetCurrentInstant(); DateTime dateTimeUtc = other.ToDateTimeUtc(); int hourOfDay = arenaType == ArenaType.Squad ? 18 : 19; Instant instant = Instant.FromUtc(dateTimeUtc.Year, dateTimeUtc.Month, dateTimeUtc.Day, hourOfDay, 0, 0).Minus(Duration.FromMinutes((long)offsetMinutes)); return(instant >= other?instant.Minus(other) : instant.Plus(Duration.FromHours(24)).Minus(other)); }
private ZoneTransition GetNext(Instant nextInstant) { // Find next matching rule. ZoneRecurrence nextRule = null; Instant nextTicks = Instant.MaxValue; for (int i = 0; i < rules.Count; i++) { ZoneRecurrence rule = rules[i]; Transition? nextTransition = rule.Next(nextInstant, ruleSet.StandardOffset, savings); Instant? next = nextTransition == null ? (Instant?)null : nextTransition.Value.Instant; if (!next.HasValue || next.Value <= nextInstant) { rules.RemoveAt(i); i--; continue; } // Even if next is same as previous next, choose the rule in order for more // recently added rules to override. if (next.Value <= nextTicks) { // Found a better match. nextRule = rule; nextTicks = next.Value; } } if (nextRule == null) { return(null); } // Stop precalculating if year reaches some arbitrary limit. We can cheat in the // conversion because it is an approximation anyway. if (calendar.GetYear(nextTicks.Plus(Offset.Zero)) >= YearLimit) { return(null); } // Check if upper limit reached or passed. if (ruleSet.upperYear < Int32.MaxValue) { Instant upperTicks = ruleSet.upperYearOffset.MakeInstant(ruleSet.upperYear, ruleSet.StandardOffset, savings); if (nextTicks >= upperTicks) { // At or after upper limit. return(null); } } return(new ZoneTransition(nextTicks, nextRule.Name, ruleSet.StandardOffset, nextRule.Savings)); }
public void Can_Write_Instant_Stored_As_Int64() { using (ISession session = SessionFactory.OpenSession()) using (ITransaction transaction = session.BeginTransaction()) { Instant startInstant = TestClock.Now; var testEvent = new InstantTestEntity { Description = "Can_Write_Instant_Stored_As_Int64", StartInstant = startInstant, FinishInstant = startInstant.Plus(Duration.FromHours(1)) }; session.Save(testEvent); transaction.Commit(); Assert.That(testEvent.Id, Is.Not.Null); } }
private async Task EnqueueJobAsync(string payload, IWebhookEntity webhook, AppEvent contentEvent, string eventName, Instant now) { var signature = $"{payload}{webhook.SharedSecret}".Sha256Base64(); var job = new WebhookJob { Id = Guid.NewGuid(), AppId = contentEvent.AppId.Id, RequestUrl = webhook.Url, RequestBody = payload, RequestSignature = signature, EventName = eventName, Expires = now.Plus(ExpirationTime), WebhookId = webhook.Id }; await webhookEventRepository.EnqueueAsync(job, now); }