2 * Copyright 2004 The Apache Software Foundation
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
19 namespace Lucene
.Net
.Documents
22 /// <summary> Provides support for converting dates to strings and vice-versa.
23 /// The strings are structured so that lexicographic sorting orders
24 /// them by date, which makes them suitable for use as field values
27 /// <P>This class also helps you to limit the resolution of your dates. Do not
28 /// save dates with a finer resolution than you really need, as then
29 /// RangeQuery and PrefixQuery will require more memory and become slower.
31 /// <P>Compared to {@link DateField} the strings generated by the methods
32 /// in this class take slightly more space, unless your selected resolution
33 /// is set to <code>Resolution.DAY</code> or lower.
35 public class DateTools
42 /// <summary> Converts a Date to a string suitable for indexing.
45 /// <param name="date">the date to be converted
47 /// <param name="resolution">the desired resolution, see
48 /// {@link #Round(Date, DateTools.Resolution)}
50 /// <returns> a string in format <code>yyyyMMddHHmmssSSS</code> or shorter,
51 /// depeding on <code>resolution</code>
53 public static System
.String
DateToString(System
.DateTime date
, Resolution resolution
)
55 return TimeToString(date
.Ticks
, resolution
);
58 /// <summary> Converts a millisecond time to a string suitable for indexing.
61 /// <param name="time">the date expressed as milliseconds since January 1, 1970, 00:00:00 GMT
63 /// <param name="resolution">the desired resolution, see
64 /// {@link #Round(long, DateTools.Resolution)}
66 /// <returns> a string in format <code>yyyyMMddHHmmssSSS</code> or shorter,
67 /// depeding on <code>resolution</code>
69 public static System
.String
TimeToString(long time
, Resolution resolution
)
71 System
.Globalization
.Calendar cal
= new System
.Globalization
.GregorianCalendar(); // {{Aroush}} do we care about 'cal'
73 //protected in JDK's prior to 1.4
74 //cal.setTimeInMillis(round(time, resolution));
76 System
.DateTime dt
= new System
.DateTime(Round(time
, resolution
));
80 if (resolution
== Resolution
.YEAR
)
82 t
= dt
.ToString("yyyy");
84 else if (resolution
== Resolution
.MONTH
)
86 t
= dt
.ToString("yyyyMM");
88 else if (resolution
== Resolution
.DAY
)
90 t
= dt
.ToString("yyyyMMdd");
92 else if (resolution
== Resolution
.HOUR
)
94 t
= dt
.ToString("yyyyMMddHH");
96 else if (resolution
== Resolution
.MINUTE
)
98 t
= dt
.ToString("yyyyMMddHHmm");
100 else if (resolution
== Resolution
.SECOND
)
102 t
= dt
.ToString("yyyyMMddHHmmss");
104 else if (resolution
== Resolution
.MILLISECOND
)
106 t
= dt
.ToString("yyyyMMddHHmmssfff");
110 throw new System
.ArgumentException("unknown resolution " + resolution
);
116 /// <summary> Converts a string produced by <code>timeToString</code> or
117 /// <code>DateToString</code> back to a time, represented as the
118 /// number of milliseconds since January 1, 1970, 00:00:00 GMT.
121 /// <param name="dateString">the date string to be converted
123 /// <returns> the number of milliseconds since January 1, 1970, 00:00:00 GMT
125 /// <throws> ParseException if <code>dateString</code> is not in the </throws>
126 /// <summary> expected format
128 public static long StringToTime(System
.String dateString
)
130 return StringToDate(dateString
).Ticks
;
133 /// <summary> Converts a string produced by <code>timeToString</code> or
134 /// <code>DateToString</code> back to a time, represented as a
138 /// <param name="dateString">the date string to be converted
140 /// <returns> the parsed time as a Date object
142 /// <throws> ParseException if <code>dateString</code> is not in the </throws>
143 /// <summary> expected format
145 public static System
.DateTime
StringToDate(System
.String dateString
)
147 System
.String yyyy
= "1";
148 System
.String MM
= "1";
149 System
.String dd
= "1";
150 System
.String HH
= "0";
151 System
.String mm
= "0";
152 System
.String ss
= "0";
153 System
.String SSS
= "0";
155 if (dateString
.Length
== 4) // "yyyy"
157 yyyy
= dateString
.Substring(0, 4);
159 else if (dateString
.Length
== 6) // "yyyyMM";
161 yyyy
= dateString
.Substring(0, 4);
162 MM
= dateString
.Substring(4, 2);
164 else if (dateString
.Length
== 8) // "yyyyMMdd"
166 yyyy
= dateString
.Substring(0, 4);
167 MM
= dateString
.Substring(4, 2);
168 dd
= dateString
.Substring(6, 2);
170 else if (dateString
.Length
== 10) // "yyyyMMddHH"
172 yyyy
= dateString
.Substring(0, 4);
173 MM
= dateString
.Substring(4, 2);
174 dd
= dateString
.Substring(6, 2);
175 HH
= dateString
.Substring(8, 2);
177 else if (dateString
.Length
== 12) // "yyyyMMddHHmm";
179 yyyy
= dateString
.Substring(0, 4);
180 MM
= dateString
.Substring(4, 2);
181 dd
= dateString
.Substring(6, 2);
182 HH
= dateString
.Substring(8, 2);
183 mm
= dateString
.Substring(10, 2);
185 else if (dateString
.Length
== 14) // "yyyyMMddHHmmss";
187 yyyy
= dateString
.Substring(0, 4);
188 MM
= dateString
.Substring(4, 2);
189 dd
= dateString
.Substring(6, 2);
190 HH
= dateString
.Substring(8, 2);
191 mm
= dateString
.Substring(10, 2);
192 ss
= dateString
.Substring(12, 2);
194 else if (dateString
.Length
== 17) // "yyyyMMddHHmmssSSS";
196 yyyy
= dateString
.Substring(0, 4);
197 MM
= dateString
.Substring(4, 2);
198 dd
= dateString
.Substring(6, 2);
199 HH
= dateString
.Substring(8, 2);
200 mm
= dateString
.Substring(10, 2);
201 ss
= dateString
.Substring(12, 2);
202 SSS
= dateString
.Substring(14, 3);
206 throw new System
.FormatException("Input is not valid date string: " + dateString
);
209 int y
, M
, d
, H
, m
, s
, S
;
210 y
= Convert
.ToInt16(yyyy
);
211 M
= Convert
.ToInt16(MM
);
212 d
= Convert
.ToInt16(dd
);
213 H
= Convert
.ToInt16(HH
);
214 m
= Convert
.ToInt16(mm
);
215 s
= Convert
.ToInt16(ss
);
216 S
= Convert
.ToInt16(SSS
);
218 return new System
.DateTime(y
,
222 //return new System.DateTime(Convert.ToInt16(yyyy),
223 // Convert.ToInt16(MM), Convert.ToInt16(dd), Convert.ToInt16(HH),
224 // Convert.ToInt16(mm), Convert.ToInt16(ss), Convert.ToInt16(SSS));
227 /// <summary> Limit a date's resolution. For example, the date <code>2004-09-21 13:50:11</code>
228 /// will be changed to <code>2004-09-01 00:00:00</code> when using
229 /// <code>Resolution.MONTH</code>.
232 /// <param name="resolution">The desired resolution of the date to be returned
234 /// <returns> the date with all values more precise than <code>resolution</code>
237 public static System
.DateTime
Round(System
.DateTime date
, Resolution resolution
)
239 return new System
.DateTime(Round(date
.Ticks
, resolution
));
242 /// <summary> Limit a date's resolution. For example, the date <code>1095767411000</code>
243 /// (which represents 2004-09-21 13:50:11) will be changed to
244 /// <code>1093989600000</code> (2004-09-01 00:00:00) when using
245 /// <code>Resolution.MONTH</code>.
248 /// <param name="resolution">The desired resolution of the date to be returned
250 /// <returns> the date with all values more precise than <code>resolution</code>
251 /// set to 0 or 1, expressed as milliseconds since January 1, 1970, 00:00:00 GMT
253 public static long Round(long time
, Resolution resolution
)
255 System
.Globalization
.Calendar cal
= new System
.Globalization
.GregorianCalendar(); // {{Aroush}} do we care about 'cal'
257 // protected in JDK's prior to 1.4
258 //cal.setTimeInMillis(time);
260 System
.DateTime dt
= new System
.DateTime(time
);
262 if (resolution
== Resolution
.YEAR
)
264 dt
= dt
.AddMonths(1 - dt
.Month
);
265 dt
= dt
.AddDays(1 - dt
.Day
);
266 dt
= dt
.AddHours(0 - dt
.Hour
);
267 dt
= dt
.AddMinutes(0 - dt
.Minute
);
268 dt
= dt
.AddSeconds(0 - dt
.Second
);
269 dt
= dt
.AddMilliseconds(0 - dt
.Millisecond
);
271 else if (resolution
== Resolution
.MONTH
)
273 dt
= dt
.AddDays(1 - dt
.Day
);
274 dt
= dt
.AddHours(0 - dt
.Hour
);
275 dt
= dt
.AddMinutes(0 - dt
.Minute
);
276 dt
= dt
.AddSeconds(0 - dt
.Second
);
277 dt
= dt
.AddMilliseconds(0 - dt
.Millisecond
);
279 else if (resolution
== Resolution
.DAY
)
281 dt
= dt
.AddHours(0 - dt
.Hour
);
282 dt
= dt
.AddMinutes(0 - dt
.Minute
);
283 dt
= dt
.AddSeconds(0 - dt
.Second
);
284 dt
= dt
.AddMilliseconds(0 - dt
.Millisecond
);
286 else if (resolution
== Resolution
.HOUR
)
288 dt
= dt
.AddMinutes(0 - dt
.Minute
);
289 dt
= dt
.AddSeconds(0 - dt
.Second
);
290 dt
= dt
.AddMilliseconds(0 - dt
.Millisecond
);
292 else if (resolution
== Resolution
.MINUTE
)
294 dt
= dt
.AddSeconds(0 - dt
.Second
);
295 dt
= dt
.AddMilliseconds(0 - dt
.Millisecond
);
297 else if (resolution
== Resolution
.SECOND
)
299 dt
= dt
.AddMilliseconds(0 - dt
.Millisecond
);
301 else if (resolution
== Resolution
.MILLISECOND
)
303 // don't cut off anything
307 throw new System
.ArgumentException("unknown resolution " + resolution
);
312 public class Resolution
314 public static readonly Resolution YEAR
= new Resolution("year");
315 public static readonly Resolution MONTH
= new Resolution("month");
316 public static readonly Resolution DAY
= new Resolution("day");
317 public static readonly Resolution HOUR
= new Resolution("hour");
318 public static readonly Resolution MINUTE
= new Resolution("minute");
319 public static readonly Resolution SECOND
= new Resolution("second");
320 public static readonly Resolution MILLISECOND
= new Resolution("millisecond");
322 private System
.String resolution
;
324 internal Resolution()
328 internal Resolution(System
.String resolution
)
330 this.resolution
= resolution
;
333 public override System
.String
ToString()