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);
        }
示例#2
0
        /// <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();
        }
示例#5
0
        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));
        }