< Summary - Code Coverage

Information
Class: Plainquire.Filter.DateTimeRangeExtensions
Assembly: Plainquire.Filter
File(s): /home/runner/work/plainquire/plainquire/Plainquire.Filter/Plainquire.Filter/Extensions/DateTimeRangeExtensions.cs
Tag: 64_13932151703
Line coverage
68%
Covered lines: 26
Uncovered lines: 12
Coverable lines: 38
Total lines: 113
Line coverage: 68.4%
Branch coverage
75%
Covered branches: 21
Total branches: 28
Branch coverage: 75%
Method coverage
50%
Covered methods: 3
Total methods: 6
Method coverage: 50%

Metrics

File(s)

/home/runner/work/plainquire/plainquire/Plainquire.Filter/Plainquire.Filter/Extensions/DateTimeRangeExtensions.cs

#LineLine coverage
 1using Chronic.Core;
 2using Plainquire.Filter.Abstractions;
 3using System;
 4using System.Diagnostics.CodeAnalysis;
 5using System.Globalization;
 6using System.Text.RegularExpressions;
 7
 8namespace Plainquire.Filter;
 9
 10/// <summary>
 11/// Extension methods for <see cref="DateTime"/>.
 12/// </summary>
 13[SuppressMessage("ReSharper", "UnusedMember.Global", Justification = "Provided as library, can be used from outside")]
 14public static class DateTimeRangeExtensions
 15{
 16    /// <summary>
 17    /// Convert a string to <see cref="DateTimeOffset"/>.
 18    /// </summary>
 19    /// <param name="value">The string to convert.</param>
 20    /// <param name="now">Value used for 'now' when parsing relative date/time values (e.g. one-week-ago).</param>
 21    /// <param name="cultureInfo">The culture to use when parsing.</param>
 22    public static DateTimeOffset ConvertStringToDateTimeOffset(this string? value, DateTimeOffset now, CultureInfo? cult
 23    {
 024        if (TryConvertStringToDateTimeRange(value, now, out var dateTimeRange, cultureInfo))
 025            return dateTimeRange.Start;
 026        throw new ArgumentException($"{value} could not be converted to date/time range", nameof(value));
 27    }
 28
 29    /// <summary>
 30    /// Try to convert a string to <see cref="DateTimeOffset"/>.
 31    /// </summary>
 32    /// <param name="value">The string to convert.</param>
 33    /// <param name="now">Value used for 'now' when parsing relative date/time values (e.g. one-week-ago).</param>
 34    /// <param name="dateTimeOffset">The parsed <see cref="DateTimeOffset"/>.</param>
 35    /// <param name="cultureInfo">The culture to use when parsing.</param>
 36    public static bool TryConvertStringToDateTimeOffset(this string? value, DateTimeOffset now, out DateTimeOffset dateT
 37    {
 038        if (TryConvertStringToDateTimeRange(value, now, out var dateTimeRange, cultureInfo))
 39        {
 040            dateTimeOffset = dateTimeRange.Start;
 041            return true;
 42        }
 43
 044        dateTimeOffset = DateTimeOffset.MinValue;
 045        return false;
 46    }
 47
 48    /// <summary>
 49    /// Convert a string to date time range.
 50    /// </summary>
 51    /// <param name="value">The string to convert.</param>
 52    /// <param name="now">Value used for 'now' when parsing relative date/time values (e.g. one-week-ago).</param>
 53    /// <param name="cultureInfo">The culture to use when parsing.</param>
 54    public static Range<DateTimeOffset> ConvertStringToDateTimeRange(this string? value, DateTimeOffset now, CultureInfo
 55    {
 056        if (TryConvertStringToDateTimeRange(value, now, out var dateTimeRange, cultureInfo))
 057            return dateTimeRange;
 058        throw new ArgumentException($"{value} could not be converted to date/time range", nameof(value));
 59    }
 60
 61    /// <summary>
 62    /// Try to convert a string to date time range.
 63    /// </summary>
 64    /// <param name="value">The string to convert.</param>
 65    /// <param name="now">Value used for 'now' when parsing relative date/time values (e.g. one-week-ago).</param>
 66    /// <param name="dateTimeRange">The parsed date time range.</param>
 67    /// <param name="cultureInfo">The culture to use when parsing.</param>
 68    public static bool TryConvertStringToDateTimeRange(this string? value, DateTimeOffset now, out Range<DateTimeOffset>
 69    {
 717970        dateTimeRange = new Range<DateTimeOffset>(DateTimeOffset.MinValue, DateTimeOffset.MinValue);
 71
 717972        if (value == null)
 073            return false;
 74
 717975        if (Abstractions.DateTimeRangeExtensions.TryConvertDateTimeRangeFormattedString(value, cultureInfo, out dateTime
 158476            return true;
 559577        if (Abstractions.DateTimeRangeExtensions.TryConvertIso8601FormattedString(value, cultureInfo, out dateTimeRange)
 436778            return true;
 122879        if (TryConvertChronicRangeFormattedString(value, now, out dateTimeRange))
 14480            return true;
 108481        if (Abstractions.DateTimeRangeExtensions.TryConvertUnknownFormattedString(value, cultureInfo, out dateTimeRange)
 14482            return true;
 83
 94084        return false;
 85    }
 86
 87    [SuppressMessage("Design", "MA0132:Do not convert implicitly to DateTimeOffset", Justification = "Used library Chron
 88    private static bool TryConvertChronicRangeFormattedString(string value, DateTimeOffset now, out Range<DateTimeOffset
 89    {
 122890        dateTimeRange = new Range<DateTimeOffset>(DateTimeOffset.MinValue, DateTimeOffset.MinValue);
 91
 122892        var startAndEnd = Regex.Match(value, "^(?<start>.*?)(_(?<end>(.*)))?$", RegexOptions.ExplicitCapture, RegexDefau
 122893        var startValue = RemoveHyphenForChronicParse(startAndEnd.Groups["start"].Value);
 122894        var endValue = RemoveHyphenForChronicParse(startAndEnd.Groups["end"].Value);
 122895        var endIsEmpty = string.IsNullOrWhiteSpace(endValue);
 96
 122897        var options = new Options { Clock = () => now.DateTime };
 122898        var start = new Parser(options).Parse(startValue);
 122899        var end = new Parser(options).Parse(endValue);
 100
 1228101        if (start != null && endIsEmpty)
 72102            end = new Span(now.DateTime, now.DateTime);
 103
 1228104        if (!startAndEnd.Success || start?.Start == null || end?.Start == null)
 1084105            return false;
 106
 144107        dateTimeRange = new Range<DateTimeOffset>(start.Start.Value, end.Start.Value);
 144108        return true;
 109    }
 110
 111    private static string RemoveHyphenForChronicParse(string value)
 2456112        => Regex.Replace(value, "-(?<word>[a-z0-9])", " ${word}", RegexOptions.ExplicitCapture, RegexDefaults.Timeout);
 113}