├── .github
├── FUNDING.yml
├── dependabot.yml
├── workflows
│ └── build.yml
├── copilot-instructions.md
└── instructions
│ ├── testing.instructions.md
│ └── general.instructions.md
├── .vscode
├── settings.json
└── tasks.json
├── tests
└── Exceptionless.DateTimeExtensions.Tests
│ ├── Properties
│ └── AssemblyInfo.cs
│ ├── RandomHelper.cs
│ ├── Exceptionless.DateTimeExtensions.Tests.csproj
│ ├── FormatParsers
│ ├── PartParsers
│ │ ├── YearPartParserTests.cs
│ │ ├── MonthPartParserTests.cs
│ │ ├── NamedDayPartParserTests.cs
│ │ ├── PartParserTestsBase.cs
│ │ ├── MonthDayPartParserTests.cs
│ │ ├── AmountTimeRelationPartParserTests.cs
│ │ ├── MonthRelationPartParserTests.cs
│ │ ├── ExplicitDatePartParserTests.cs
│ │ ├── SingleTimeRelationPartParserTests.cs
│ │ ├── WildcardPartParserTests.cs
│ │ └── DateMathPartParserTests.cs
│ ├── YearFormatParserTests.cs
│ ├── NamedDayFormatParserTests.cs
│ ├── MonthFormatParserTests.cs
│ ├── MonthDayFormatParserTests.cs
│ ├── FormatParserTestsBase.cs
│ ├── RelationAmountTimeFormatParserTests.cs
│ ├── MonthRelationFormatParserTests.cs
│ ├── SingleTimeRelationFormatParserTests.cs
│ ├── ExplicitDateFormatParserTests.cs
│ └── TwoPartFormatParserTests.cs
│ ├── DateTimeExtensionsTests.cs
│ ├── TimeSpanExtensionTests.cs
│ ├── TimeUnitTests.cs
│ ├── BusinessDayTests.cs
│ └── DateTimeRangeTests.cs
├── src
└── Exceptionless.DateTimeExtensions
│ ├── Exceptionless.DateTimeExtensions.csproj
│ ├── FormatParsers
│ └── FormatParsers
│ │ ├── IFormatParser.cs
│ │ ├── PriorityAttribute.cs
│ │ ├── PartParsers
│ │ ├── IPartParser.cs
│ │ ├── YearPartParser.cs
│ │ ├── WildcardPartParser.cs
│ │ ├── MonthPartParser.cs
│ │ ├── SingleTimeRelationPartParser.cs
│ │ ├── MonthDayPartParser.cs
│ │ ├── NamedDayPartParser.cs
│ │ ├── DateMathPartParser.cs
│ │ ├── ExplicitDatePartParser.cs
│ │ ├── MonthRelationPartParser.cs
│ │ └── AmountTimeRelationPartParser.cs
│ │ ├── YearFormatParser.cs
│ │ ├── SingleTimeRelationFormatParser.cs
│ │ ├── MonthFormatParser.cs
│ │ ├── MonthDayFormatParser.cs
│ │ ├── NamedDayFormatParser.cs
│ │ ├── ExplicitDateFormatParser.cs
│ │ ├── Helper.cs
│ │ ├── MonthRelationFormatParser.cs
│ │ ├── RelationAmountTimeFormatParser.cs
│ │ └── TwoPartFormatParser.cs
│ ├── Properties
│ └── AssemblyInfo.cs
│ ├── TypeHelper.cs
│ ├── BusinessDay.cs
│ ├── TimeUnit.cs
│ ├── DateTimeRange.cs
│ ├── TimeSpanExtensions.cs
│ ├── BusinessWeek.cs
│ └── DateTimeExtensions.cs
├── Exceptionless.DateTimeExtensions.slnx
├── .gitattributes
├── .gitignore
├── .editorconfig
├── README.md
└── LICENSE.txt
/.github/FUNDING.yml:
--------------------------------------------------------------------------------
1 | github: exceptionless
2 |
--------------------------------------------------------------------------------
/.vscode/settings.json:
--------------------------------------------------------------------------------
1 | {
2 | "cSpell.words": [
3 | "millis",
4 | "timespan"
5 | ]
6 | }
--------------------------------------------------------------------------------
/.github/dependabot.yml:
--------------------------------------------------------------------------------
1 | version: 2
2 | updates:
3 | - package-ecosystem: nuget
4 | directory: "/"
5 | schedule:
6 | interval: weekly
7 | open-pull-requests-limit: 10
--------------------------------------------------------------------------------
/tests/Exceptionless.DateTimeExtensions.Tests/Properties/AssemblyInfo.cs:
--------------------------------------------------------------------------------
1 | [assembly: Xunit.CollectionBehavior(DisableTestParallelization = true, MaxParallelThreads = 1)]
2 |
--------------------------------------------------------------------------------
/src/Exceptionless.DateTimeExtensions/Exceptionless.DateTimeExtensions.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
--------------------------------------------------------------------------------
/src/Exceptionless.DateTimeExtensions/FormatParsers/FormatParsers/IFormatParser.cs:
--------------------------------------------------------------------------------
1 | using System;
2 |
3 | namespace Exceptionless.DateTimeExtensions.FormatParsers;
4 |
5 | public interface IFormatParser
6 | {
7 | DateTimeRange Parse(string content, DateTimeOffset relativeBaseTime);
8 | }
9 |
--------------------------------------------------------------------------------
/.github/workflows/build.yml:
--------------------------------------------------------------------------------
1 | name: Build
2 | on: [push, pull_request]
3 |
4 | jobs:
5 | build:
6 | uses: FoundatioFx/Foundatio/.github/workflows/build-workflow.yml@main
7 | with:
8 | org: exceptionless
9 | secrets:
10 | NUGET_KEY: ${{ secrets.NUGET_KEY }}
11 | FEEDZ_KEY: ${{ secrets.FEEDZ_KEY }}
12 |
--------------------------------------------------------------------------------
/src/Exceptionless.DateTimeExtensions/FormatParsers/FormatParsers/PriorityAttribute.cs:
--------------------------------------------------------------------------------
1 | using System;
2 |
3 | namespace Exceptionless.DateTimeExtensions.FormatParsers;
4 |
5 | public class PriorityAttribute : Attribute
6 | {
7 | public PriorityAttribute(int priority)
8 | {
9 | Priority = priority;
10 | }
11 |
12 | public int Priority { get; private set; }
13 | }
14 |
--------------------------------------------------------------------------------
/src/Exceptionless.DateTimeExtensions/FormatParsers/FormatParsers/PartParsers/IPartParser.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Text.RegularExpressions;
3 |
4 | namespace Exceptionless.DateTimeExtensions.FormatParsers.PartParsers;
5 |
6 | public interface IPartParser
7 | {
8 | Regex Regex { get; }
9 | DateTimeOffset? Parse(Match match, DateTimeOffset relativeBaseTime, bool isUpperLimit);
10 | }
11 |
--------------------------------------------------------------------------------
/Exceptionless.DateTimeExtensions.slnx:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
--------------------------------------------------------------------------------
/src/Exceptionless.DateTimeExtensions/Properties/AssemblyInfo.cs:
--------------------------------------------------------------------------------
1 | using System.Runtime.CompilerServices;
2 |
3 | [assembly: InternalsVisibleTo("Exceptionless.DateTimeExtensions.Tests, PublicKey=0024000004800000940000000602000000240000525341310004000001000100a9357232b9bcad78fd310297fdb41bf42816ee2ca9ccdace999889de2badb6f06df2de1d9f2c8cb17b21f5311f11d6bb328d55e0dd9fe8adc5e2dc4610028c1bdacb3355d2e239b81d0bb0ac83e615fc641f8a3ec49e4fad8e305994953d448ef7b38e8c256601e54af19c035b562e3e5e5461c2a93b8dd11936e451b05034a2")]
4 |
--------------------------------------------------------------------------------
/src/Exceptionless.DateTimeExtensions/FormatParsers/FormatParsers/PartParsers/YearPartParser.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Text.RegularExpressions;
3 |
4 | namespace Exceptionless.DateTimeExtensions.FormatParsers.PartParsers;
5 |
6 | [Priority(70)]
7 | public class YearPartParser : IPartParser
8 | {
9 | private static readonly Regex _parser = new(@"\G(?\d{4})", RegexOptions.Compiled);
10 | public Regex Regex => _parser;
11 |
12 | public DateTimeOffset? Parse(Match match, DateTimeOffset relativeBaseTime, bool isUpperLimit)
13 | {
14 | int year = Int32.Parse(match.Groups["year"].Value);
15 | return isUpperLimit ? relativeBaseTime.ChangeYear(year).EndOfYear() : relativeBaseTime.ChangeYear(year).StartOfYear();
16 | }
17 | }
18 |
--------------------------------------------------------------------------------
/src/Exceptionless.DateTimeExtensions/FormatParsers/FormatParsers/PartParsers/WildcardPartParser.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Text.RegularExpressions;
3 |
4 | namespace Exceptionless.DateTimeExtensions.FormatParsers.PartParsers;
5 |
6 | [Priority(1)]
7 | public class WildcardPartParser : IPartParser
8 | {
9 | private static readonly Regex _wildcardRegex = new(@"\G\s*\*(?=\s|\]|\}|$)", RegexOptions.Compiled | RegexOptions.IgnoreCase);
10 |
11 | public Regex Regex => _wildcardRegex;
12 |
13 | public DateTimeOffset? Parse(Match match, DateTimeOffset relativeBaseTime, bool isUpperLimit)
14 | {
15 | if (!match.Success)
16 | return null;
17 |
18 | return isUpperLimit ? DateTimeOffset.MaxValue : DateTimeOffset.MinValue;
19 | }
20 | }
21 |
--------------------------------------------------------------------------------
/tests/Exceptionless.DateTimeExtensions.Tests/RandomHelper.cs:
--------------------------------------------------------------------------------
1 | using System;
2 |
3 | namespace Exceptionless.DateTimeExtensions.Tests;
4 |
5 | public static class RandomHelper
6 | {
7 | static readonly Random _rnd = new();
8 |
9 | public static DateTime GetRandomDate(DateTime from, DateTime to)
10 | {
11 | var range = to - from;
12 |
13 | var randTimeSpan = new TimeSpan((long)(_rnd.NextDouble() * range.Ticks));
14 |
15 | return from + randTimeSpan;
16 | }
17 |
18 | public static DateTimeOffset GetRandomDate(DateTimeOffset from, DateTimeOffset to)
19 | {
20 | var range = to - from;
21 |
22 | var randTimeSpan = new TimeSpan((long)(_rnd.NextDouble() * range.Ticks));
23 |
24 | return from + randTimeSpan;
25 | }
26 | }
27 |
--------------------------------------------------------------------------------
/src/Exceptionless.DateTimeExtensions/FormatParsers/FormatParsers/YearFormatParser.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Text.RegularExpressions;
3 |
4 | namespace Exceptionless.DateTimeExtensions.FormatParsers;
5 |
6 | [Priority(80)]
7 | public class YearFormatParser : IFormatParser
8 | {
9 | private static readonly Regex _parser = new(@"^\s*(?\d{4})\s*$", RegexOptions.Compiled);
10 |
11 | public DateTimeRange Parse(string content, DateTimeOffset relativeBaseTime)
12 | {
13 | var m = _parser.Match(content);
14 | if (!m.Success)
15 | return null;
16 |
17 | int year = Int32.Parse(m.Groups["year"].Value);
18 | return new DateTimeRange(relativeBaseTime.ChangeYear(year).StartOfYear(), relativeBaseTime.ChangeYear(year).EndOfYear());
19 | }
20 | }
21 |
--------------------------------------------------------------------------------
/src/Exceptionless.DateTimeExtensions/FormatParsers/FormatParsers/SingleTimeRelationFormatParser.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Text.RegularExpressions;
3 |
4 | namespace Exceptionless.DateTimeExtensions.FormatParsers;
5 |
6 | [Priority(70)]
7 | public class SingleTimeRelationFormatParser : RelationAmountTimeFormatParser
8 | {
9 | private static readonly Regex _parser = new(String.Format(@"^\s*(?{0})\s+(?