public void GivenAPartialDateTimeWithNoMissingComponent_WhenToDateTimeOffsetIsCalled_ThenCorrectDateTimeOffsetIsReturned() { PartialDateTime dateTime = _builder.ToPartialDateTime(); DateTimeOffset actualOffset = dateTime.ToDateTimeOffset( 2, (year, month) => 10, 15, 13, 12, 0.300250m, TimeSpan.FromMinutes(30)); DateTimeOffset expectedOffset = new DateTimeOffset( DefaultYear, DefaultMonth, DefaultDay, DefaultHour, DefaultMinute, DefaultSecond, DefaultUtcOffset); expectedOffset = expectedOffset.AddTicks((long)(DefaultFraction * TimeSpan.TicksPerSecond)); Assert.Equal(expectedOffset, actualOffset); }
/// <summary> /// Initializes a new instance of the <see cref="DateTimeSearchValue"/> class. /// </summary> /// <param name="startDateTime">The start date time.</param> /// <param name="endDateTime">The end date time.</param> public DateTimeSearchValue(PartialDateTime startDateTime, PartialDateTime endDateTime) { Start = startDateTime.ToDateTimeOffset( defaultMonth: 1, defaultDaySelector: (year, month) => 1, defaultHour: 0, defaultMinute: 0, defaultSecond: 0, defaultFraction: 0.0000000m, defaultUtcOffset: TimeSpan.Zero).ToUniversalTime(); End = endDateTime.ToDateTimeOffset( defaultMonth: 12, defaultDaySelector: (year, month) => DateTime.DaysInMonth(year, month), defaultHour: 23, defaultMinute: 59, defaultSecond: 59, defaultFraction: 0.9999999m, defaultUtcOffset: TimeSpan.Zero).ToUniversalTime(); if (Start > End) { string message = $"The evaluated value of parameter '{nameof(startDateTime)}' cannot be greater than the evaluated value of parameter '{nameof(endDateTime)}'. " + $"The parameter '{nameof(startDateTime)}' evaluated to '{Start:o}' and the parameter '{nameof(endDateTime)}' evaluated to '{End:o}'."; throw new ArgumentOutOfRangeException( nameof(startDateTime), message); } }
public void GivenAPartialDateTimeWithMissingComponents_WhenToDateTimeOffsetIsCalled_ThenCorrectDateTimeOffsetIsReturned() { int expectedMonth = 2; int expectedDay = 10; int expectedHour = 15; int expectedMinute = 13; int expectedSecond = 12; decimal expectedFraction = 0.3009953m; TimeSpan expectedUtcOffset = TimeSpan.FromMinutes(30); _builder.Month = null; _builder.Day = null; _builder.Hour = null; _builder.Minute = null; _builder.Second = null; _builder.Fraction = null; _builder.UtcOffset = null; PartialDateTime dateTime = _builder.ToPartialDateTime(); DateTimeOffset actualOffset = dateTime.ToDateTimeOffset( expectedMonth, (year, month) => expectedDay, expectedHour, expectedMinute, expectedSecond, expectedFraction, expectedUtcOffset); DateTimeOffset expectedOffset = new DateTimeOffset( DefaultYear, expectedMonth, expectedDay, expectedHour, expectedMinute, expectedSecond, expectedUtcOffset); expectedOffset = expectedOffset.AddTicks((long)(expectedFraction * TimeSpan.TicksPerSecond)); Assert.Equal(expectedOffset, actualOffset); }
/// <summary> /// Initializes a new instance of the <see cref="DateTimeSearchValue"/> class. /// </summary> /// <param name="startDateTime">The start date time.</param> /// <param name="endDateTime">The end date time.</param> public DateTimeSearchValue(PartialDateTime startDateTime, PartialDateTime endDateTime) { Start = startDateTime.ToDateTimeOffset( defaultMonth: 1, defaultDaySelector: (year, month) => 1, defaultHour: 0, defaultMinute: 0, defaultSecond: 0, defaultFraction: 0.0000000m, defaultUtcOffset: TimeSpan.Zero).ToUniversalTime(); End = endDateTime.ToDateTimeOffset( defaultMonth: 12, defaultDaySelector: (year, month) => DateTime.DaysInMonth(year, month), defaultHour: 23, defaultMinute: 59, defaultSecond: 59, defaultFraction: 0.9999999m, defaultUtcOffset: TimeSpan.Zero).ToUniversalTime(); }
public async Task <ResourceElement> SearchHistoryAsync( string resourceType, string resourceId, PartialDateTime at, PartialDateTime since, PartialDateTime before, int?count, string continuationToken, CancellationToken cancellationToken) { var queryParameters = new List <Tuple <string, string> >(); if (at != null) { if (since != null) { // _at and _since cannot be both specified. throw new InvalidSearchOperationException( string.Format( CultureInfo.InvariantCulture, Core.Resources.AtCannotBeSpecifiedWithBeforeOrSince, KnownQueryParameterNames.At, KnownQueryParameterNames.Since)); } if (before != null) { // _at and _since cannot be both specified. throw new InvalidSearchOperationException( string.Format( CultureInfo.InvariantCulture, Core.Resources.AtCannotBeSpecifiedWithBeforeOrSince, KnownQueryParameterNames.At, KnownQueryParameterNames.Before)); } } if (before != null) { var beforeOffset = before.ToDateTimeOffset( defaultMonth: 1, defaultDaySelector: (year, month) => 1, defaultHour: 0, defaultMinute: 0, defaultSecond: 0, defaultFraction: 0.0000000m, defaultUtcOffset: TimeSpan.Zero).ToUniversalTime(); if (beforeOffset.CompareTo(Clock.UtcNow) > 0) { // you cannot specify a value for _before in the future throw new InvalidSearchOperationException( string.Format( CultureInfo.InvariantCulture, Core.Resources.HistoryParameterBeforeCannotBeFuture, KnownQueryParameterNames.Before)); } } bool searchByResourceId = !string.IsNullOrEmpty(resourceId); if (searchByResourceId) { queryParameters.Add(Tuple.Create(SearchParameterNames.Id, resourceId)); } if (!string.IsNullOrEmpty(continuationToken)) { queryParameters.Add(Tuple.Create(KnownQueryParameterNames.ContinuationToken, continuationToken)); } if (at != null) { queryParameters.Add(Tuple.Create(SearchParameterNames.LastUpdated, at.ToString())); } else { if (since != null) { queryParameters.Add(Tuple.Create(SearchParameterNames.LastUpdated, $"ge{since}")); } if (before != null) { queryParameters.Add(Tuple.Create(SearchParameterNames.LastUpdated, $"lt{before}")); } } if (count.HasValue && count > 0) { queryParameters.Add(Tuple.Create(KnownQueryParameterNames.Count, count.ToString())); } SearchOptions searchOptions = !string.IsNullOrEmpty(resourceType) ? _searchOptionsFactory.Create(resourceType, queryParameters) : _searchOptionsFactory.Create(queryParameters); SearchResult searchResult = await SearchHistoryInternalAsync(searchOptions, cancellationToken); // If no results are returned from the _history search // determine if the resource actually exists or if the results were just filtered out. // The 'deleted' state has no effect because history will return deleted resources if (searchByResourceId && searchResult.Results.Any() == false) { var resource = await _fhirDataStore.GetAsync(new ResourceKey(resourceType, resourceId), cancellationToken); if (resource == null) { throw new ResourceNotFoundException(string.Format(Core.Resources.ResourceNotFoundById, resourceType, resourceId)); } } return(_bundleFactory.CreateHistoryBundle( unsupportedSearchParams: null, result: searchResult)); }