-
-
Notifications
You must be signed in to change notification settings - Fork 2
/
TimeSpanParser.cs
135 lines (120 loc) · 4.35 KB
/
TimeSpanParser.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
using System.Diagnostics.CodeAnalysis;
namespace X10D.Time;
/// <summary>
/// Represents a class which contains a <see cref="string" /> parser which converts into <see cref="TimeSpan" />.
/// </summary>
public static class TimeSpanParser
{
/// <summary>
/// Attempts to parses a shorthand time span string (e.g. 3w 2d 1h), converting it to an instance of
/// <see cref="TimeSpan" /> which represents that duration of time.
/// </summary>
/// <param name="value">
/// The input string. Floating point is not supported, but range the following units are supported:
///
/// <list type="table">
/// <listheader>
/// <term>Suffix</term>
/// <description>Meaning</description>
/// </listheader>
///
/// <item>
/// <term>ms</term>
/// <description>Milliseconds</description>
/// </item>
/// <item>
/// <term>s</term>
/// <description>Seconds</description>
/// </item>
/// <item>
/// <term>m</term>
/// <description>Minutes</description>
/// </item>
/// <item>
/// <term>h</term>
/// <description>Hours</description>
/// </item>
/// <item>
/// <term>d</term>
/// <description>Days</description>
/// </item>
/// <item>
/// <term>w</term>
/// <description>Weeks</description>
/// </item>
/// <item>
/// <term>mo</term>
/// <description>Months</description>
/// </item>
/// <item>
/// <term>y</term>
/// <description>Years</description>
/// </item>
/// </list>
/// </param>
/// <param name="result">When this method returns, contains the parsed result.</param>
/// <returns><see langword="true" /> if the parse was successful, <see langword="false" /> otherwise.</returns>
public static bool TryParse([NotNullWhen(true)] string? value, out TimeSpan result)
{
result = TimeSpan.Zero;
if (string.IsNullOrWhiteSpace(value))
{
return false;
}
var unitValue = 0;
for (var index = 0; index < value.Length; index++)
{
char current = value[index];
switch (current)
{
case var digitChar when char.IsDigit(digitChar):
var digit = (int)char.GetNumericValue(digitChar);
unitValue = unitValue * 10 + digit;
break;
case 'y':
result += TimeSpan.FromDays(unitValue * 365);
unitValue = 0;
break;
case 'm':
if (index < value.Length - 1 && value[index + 1] == 'o')
{
index++;
result += TimeSpan.FromDays(unitValue * 30);
}
else if (index < value.Length - 1 && value[index + 1] == 's')
{
index++;
result += TimeSpan.FromMilliseconds(unitValue);
}
else
{
result += TimeSpan.FromMinutes(unitValue);
}
unitValue = 0;
break;
case 'w':
result += TimeSpan.FromDays(unitValue * 7);
unitValue = 0;
break;
case 'd':
result += TimeSpan.FromDays(unitValue);
unitValue = 0;
break;
case 'h':
result += TimeSpan.FromHours(unitValue);
unitValue = 0;
break;
case 's':
result += TimeSpan.FromSeconds(unitValue);
unitValue = 0;
break;
case var space when char.IsWhiteSpace(space):
break;
default:
result = TimeSpan.Zero;
return false;
}
}
return true;
}
}