@@ -8,9 +8,10 @@ namespace Nest
8
8
[ JsonConverter ( typeof ( TimeJsonConverter ) ) ]
9
9
public class Time : IComparable < Time > , IEquatable < Time >
10
10
{
11
- private static readonly Regex _expressionRegex = new Regex ( @"^(?<factor>\d+(?:\.\d+)?)(?<interval>(?:y|M|w|d|h|m|s|ms))?$" , RegexOptions . Compiled | RegexOptions . ExplicitCapture ) ;
11
+ private static readonly Regex _expressionRegex = new Regex ( @"^(?<factor>[-+]? \d+(?:\.\d+)?)(?<interval>(?:y|M|w|d|h|m|s|ms))?$" , RegexOptions . Compiled | RegexOptions . ExplicitCapture ) ;
12
12
13
- private static readonly double _year = TimeSpan . FromDays ( 365 ) . TotalMilliseconds ;
13
+ private static readonly double _yearApproximate = TimeSpan . FromDays ( 365 ) . TotalMilliseconds ;
14
+ private static readonly double _monthApproximate = TimeSpan . FromDays ( 30 ) . TotalMilliseconds ;
14
15
private static readonly double _week = TimeSpan . FromDays ( 7 ) . TotalMilliseconds ;
15
16
private static readonly double _day = TimeSpan . FromDays ( 1 ) . TotalMilliseconds ;
16
17
private static readonly double _hour = TimeSpan . FromHours ( 1 ) . TotalMilliseconds ;
@@ -19,33 +20,15 @@ public class Time : IComparable<Time>, IEquatable<Time>
19
20
20
21
public double ? Factor { get ; private set ; }
21
22
public TimeUnit ? Interval { get ; private set ; }
23
+
24
+ // TODO make nullable in 3.0
22
25
public double Milliseconds { get ; private set ; }
26
+ private double ApproximateMilliseconds { get ; set ; }
23
27
24
28
public static implicit operator Time ( TimeSpan span ) => new Time ( span ) ;
25
29
public static implicit operator Time ( double milliseconds ) => new Time ( milliseconds ) ;
26
30
public static implicit operator Time ( string expression ) => new Time ( expression ) ;
27
31
28
- public Time ( double factor , TimeUnit interval )
29
- {
30
- this . Factor = factor ;
31
- this . Interval = interval ;
32
-
33
- if ( interval == TimeUnit . Year )
34
- Milliseconds = ( long ) factor * _year ;
35
- else if ( interval == TimeUnit . Week )
36
- Milliseconds = ( long ) factor * _week ;
37
- else if ( interval == TimeUnit . Day )
38
- Milliseconds = ( long ) factor * _day ;
39
- else if ( interval == TimeUnit . Hour )
40
- Milliseconds = ( long ) factor * _hour ;
41
- else if ( interval == TimeUnit . Minute )
42
- Milliseconds = ( long ) factor * _minute ;
43
- else if ( interval == TimeUnit . Second )
44
- Milliseconds = ( long ) factor * _second ;
45
- else //ms
46
- Milliseconds = ( long ) factor ;
47
- }
48
-
49
32
public Time ( TimeSpan timeSpan )
50
33
{
51
34
Reduce ( timeSpan . TotalMilliseconds ) ;
@@ -56,38 +39,36 @@ public Time(double milliseconds)
56
39
Reduce ( milliseconds ) ;
57
40
}
58
41
42
+ public Time ( double factor , TimeUnit interval )
43
+ {
44
+ this . Factor = factor ;
45
+ this . Interval = interval ;
46
+ SetMilliseconds ( this . Interval , this . Factor . Value ) ;
47
+ }
48
+
59
49
public Time ( string timeUnit )
60
50
{
61
51
if ( timeUnit . IsNullOrEmpty ( ) ) throw new ArgumentException ( "Time expression string is empty" , nameof ( timeUnit ) ) ;
62
52
var match = _expressionRegex . Match ( timeUnit ) ;
63
53
if ( ! match . Success ) throw new ArgumentException ( $ "Time expression '{ timeUnit } ' string is invalid", nameof ( timeUnit ) ) ;
64
54
65
55
this . Factor = double . Parse ( match . Groups [ "factor" ] . Value , CultureInfo . InvariantCulture ) ;
66
- this . Interval = match . Groups [ "interval" ] . Success
67
- ? match . Groups [ "interval" ] . Value . ToEnum < TimeUnit > ( )
68
- : TimeUnit . Millisecond ;
69
-
70
- if ( this . Interval == TimeUnit . Year )
71
- Milliseconds = ( long ) ( this . Factor * _year ) ;
72
- else if ( this . Interval == TimeUnit . Week )
73
- Milliseconds = ( long ) ( this . Factor * _week ) ;
74
- else if ( this . Interval == TimeUnit . Day )
75
- Milliseconds = ( long ) ( this . Factor * _day ) ;
76
- else if ( this . Interval == TimeUnit . Hour )
77
- Milliseconds = ( long ) ( this . Factor * _hour ) ;
78
- else if ( this . Interval == TimeUnit . Minute )
79
- Milliseconds = ( long ) ( this . Factor * _minute ) ;
80
- else if ( this . Interval == TimeUnit . Second )
81
- Milliseconds = ( long ) ( this . Factor * _second ) ;
82
- else //ms
83
- Milliseconds = ( long ) this . Factor ;
56
+
57
+ if ( this . Factor > 0 )
58
+ {
59
+ this . Interval = match . Groups [ "interval" ] . Success
60
+ ? match . Groups [ "interval" ] . Value . ToEnum < TimeUnit > ( StringComparison . Ordinal )
61
+ : TimeUnit . Millisecond ;
62
+ }
63
+
64
+ SetMilliseconds ( this . Interval , this . Factor . Value ) ;
84
65
}
85
66
86
67
public int CompareTo ( Time other )
87
68
{
88
69
if ( other == null ) return 1 ;
89
- if ( this . Milliseconds == other . Milliseconds ) return 0 ;
90
- if ( this . Milliseconds < other . Milliseconds ) return - 1 ;
70
+ if ( this . ApproximateMilliseconds == other . ApproximateMilliseconds ) return 0 ;
71
+ if ( this . ApproximateMilliseconds < other . ApproximateMilliseconds ) return - 1 ;
91
72
return 1 ;
92
73
}
93
74
@@ -115,7 +96,7 @@ public bool Equals(Time other)
115
96
{
116
97
if ( ReferenceEquals ( null , other ) ) return false ;
117
98
if ( ReferenceEquals ( this , other ) ) return true ;
118
- return Milliseconds == other . Milliseconds ;
99
+ return ( this . ApproximateMilliseconds == other . ApproximateMilliseconds ) ;
119
100
}
120
101
121
102
public override bool Equals ( object obj )
@@ -126,18 +107,57 @@ public override bool Equals(object obj)
126
107
return Equals ( ( Time ) obj ) ;
127
108
}
128
109
129
- public override int GetHashCode ( ) => this . Milliseconds . GetHashCode ( ) ;
110
+ public override int GetHashCode ( ) => this . ApproximateMilliseconds . GetHashCode ( ) ;
130
111
131
- private void Reduce ( double ms )
112
+ private void SetMilliseconds ( TimeUnit ? interval , double factor )
132
113
{
133
- this . Milliseconds = ms ;
114
+ this . Milliseconds = interval . HasValue ? GetExactMilliseconds ( interval . Value , factor ) : factor ;
115
+ this . ApproximateMilliseconds = interval . HasValue ? GetApproximateMilliseconds ( interval . Value , factor ) : factor ;
116
+ }
134
117
135
- if ( ms >= _year )
118
+ private double GetExactMilliseconds ( TimeUnit interval , double factor )
119
+ {
120
+ switch ( interval )
136
121
{
137
- Factor = ms / _year ;
138
- Interval = TimeUnit . Year ;
122
+
123
+ case TimeUnit . Week :
124
+ return factor * _week ;
125
+ case TimeUnit . Day :
126
+ return factor * _day ;
127
+ case TimeUnit . Hour :
128
+ return factor * _hour ;
129
+ case TimeUnit . Minute :
130
+ return factor * _minute ;
131
+ case TimeUnit . Second :
132
+ return factor * _second ;
133
+ case TimeUnit . Year :
134
+ case TimeUnit . Month :
135
+ // Cannot calculate exact milliseconds for non-fixed intervals
136
+ return - 1 ;
137
+ default : // ms
138
+ return factor ;
139
139
}
140
- else if ( ms >= _week )
140
+ }
141
+
142
+ private double GetApproximateMilliseconds ( TimeUnit interval , double factor )
143
+ {
144
+ switch ( interval )
145
+ {
146
+ case TimeUnit . Year :
147
+ return factor * _yearApproximate ;
148
+ case TimeUnit . Month :
149
+ return factor * _monthApproximate ;
150
+ default :
151
+ return GetExactMilliseconds ( interval , factor ) ;
152
+ }
153
+ }
154
+
155
+ private void Reduce ( double ms )
156
+ {
157
+ this . Milliseconds = ms ;
158
+ this . ApproximateMilliseconds = ms ;
159
+
160
+ if ( ms >= _week )
141
161
{
142
162
Factor = ms / _week ;
143
163
Interval = TimeUnit . Week ;
@@ -165,10 +185,9 @@ private void Reduce(double ms)
165
185
else
166
186
{
167
187
Factor = ms ;
168
- // If milliseconds is < 0 then don't set an interval.
188
+ // If milliseconds is <= 0 then don't set an interval.
169
189
// This is used when setting things like index.refresh_interval = -1 (the only case where a unit isn't required)
170
- if ( ms > 0 )
171
- Interval = TimeUnit . Millisecond ;
190
+ Interval = ( ms > 0 ) ? ( TimeUnit ? ) TimeUnit . Millisecond : null ;
172
191
}
173
192
}
174
193
}
0 commit comments