blob: a578fdd6893bb9055286aabf2f9d33091b1f9427 [file] [log] [blame]
Nils Diewaldf399a672013-11-18 17:55:22 +00001package de.ids_mannheim.korap.util;
2
3import java.util.*;
4import java.util.regex.*;
5
6/**
Nils Diewaldc383ed02015-02-26 21:35:22 +00007 * KrillDate implements a helper object to stringify
Nils Diewaldfe6a3652015-02-05 20:34:27 +00008 * and parse date strings optimized
9 * for integer range queries in Lucene.
10 * No support for b.c. dates.
Nils Diewaldbb33da22015-03-04 16:24:25 +000011 *
12 * Strings are parsed and serialized to {@link http
13 * ://tools.ietf.org/html/rfc3339 RFC3339} compatible strings with a
14 * day granularity according to {@link http
15 * ://www.w3.org/TR/NOTE-datetime W3-DateTimes}.
16 *
Nils Diewaldfe6a3652015-02-05 20:34:27 +000017 * <blockquote><pre>
Nils Diewaldbb33da22015-03-04 16:24:25 +000018 * KrillDate kd = new KrillDate("2005-06-03");
19 * System.err.println(kd.day());
20 * // 3
21 *
22 * kd = new KrillDate("2005-06");
23 * System.err.println(kd.month());
24 * // 6
Nils Diewaldfe6a3652015-02-05 20:34:27 +000025 * </pre></blockquote>
Nils Diewaldbb33da22015-03-04 16:24:25 +000026 *
Nils Diewaldfe6a3652015-02-05 20:34:27 +000027 * @author diewald
Nils Diewaldf399a672013-11-18 17:55:22 +000028 */
Nils Diewaldc383ed02015-02-26 21:35:22 +000029public class KrillDate {
Nils Diewaldf399a672013-11-18 17:55:22 +000030
Nils Diewaldfe6a3652015-02-05 20:34:27 +000031 /**
32 * The year of the date.
33 */
34 public int year = 0;
Nils Diewaldf399a672013-11-18 17:55:22 +000035
Nils Diewaldfe6a3652015-02-05 20:34:27 +000036
37 /**
38 * The month of the date.
39 */
40 public int month = 0;
41
42
43 /**
44 * The day of the date.
45 */
46 public int day = 0;
47
48
49 // Date string regex pattern
Nils Diewaldbb33da22015-03-04 16:24:25 +000050 private static final Pattern datePattern = Pattern
51 .compile("\\s*(\\d\\d\\d\\d)" + "(?:\\s*[-/]?\\s*(\\d\\d)"
52 + "(?:\\s*[-/]?\\s*(\\d\\d))?)?\\s*");
Nils Diewaldf399a672013-11-18 17:55:22 +000053
Nils Diewaldfe6a3652015-02-05 20:34:27 +000054 /**
55 * Static value representing the minimum date.
56 */
57 public static final int BEGINNING = 0;
Nils Diewaldf399a672013-11-18 17:55:22 +000058
Nils Diewaldf399a672013-11-18 17:55:22 +000059
Nils Diewaldfe6a3652015-02-05 20:34:27 +000060 /**
61 * Static value representing the maximum date.
62 */
63 public static final int END = 99_999_999;
64
65
66 /**
Nils Diewaldc383ed02015-02-26 21:35:22 +000067 * Construct a new KrillDate object.
Nils Diewaldfe6a3652015-02-05 20:34:27 +000068 */
Nils Diewaldbb33da22015-03-04 16:24:25 +000069 public KrillDate () {};
Nils Diewaldfe6a3652015-02-05 20:34:27 +000070
71
72 /**
Nils Diewaldc383ed02015-02-26 21:35:22 +000073 * Construct a new KrillDate object.
Nils Diewaldbb33da22015-03-04 16:24:25 +000074 *
75 * @param date
76 * The date as a string (see synopsis).
Nils Diewaldfe6a3652015-02-05 20:34:27 +000077 */
Nils Diewaldc383ed02015-02-26 21:35:22 +000078 public KrillDate (String date) {
Nils Diewaldfe6a3652015-02-05 20:34:27 +000079 if (date == null || date.isEmpty())
80 return;
81
82 // Use pattern to split string
83 Matcher m = datePattern.matcher(date);
84 if (m.matches()) {
85 this.year = Integer.parseInt(m.group(1));
86 if (m.group(2) != null)
87 this.month = Integer.parseInt(m.group(2));
88 if (m.group(3) != null)
Nils Diewaldbb33da22015-03-04 16:24:25 +000089 this.day = Integer.parseInt(m.group(3));
Nils Diewaldfe6a3652015-02-05 20:34:27 +000090 };
Nils Diewaldf399a672013-11-18 17:55:22 +000091 };
92
Nils Diewaldf399a672013-11-18 17:55:22 +000093
Nils Diewaldfe6a3652015-02-05 20:34:27 +000094 /**
95 * Get the date as an integer with ceiled values for
96 * undefined date segments.
Nils Diewaldbb33da22015-03-04 16:24:25 +000097 *
Nils Diewaldfe6a3652015-02-05 20:34:27 +000098 * <blockquote><pre>
Nils Diewaldbb33da22015-03-04 16:24:25 +000099 * KrillDate kd = new KrillDate("2005-06");
100 * System.err.println(kd.ceil());
101 * // 20050699
Nils Diewaldfe6a3652015-02-05 20:34:27 +0000102 * </pre></blockquote>
Nils Diewaldbb33da22015-03-04 16:24:25 +0000103 *
Nils Diewaldfe6a3652015-02-05 20:34:27 +0000104 * @return ceiled integer value.
105 */
Nils Diewaldf399a672013-11-18 17:55:22 +0000106 public int ceil () {
Nils Diewaldbb33da22015-03-04 16:24:25 +0000107 return (ceil((byte) 4, this.year) * 10_000)
108 + (ceil((byte) 2, this.month) * 100)
109 + (ceil((byte) 2, this.day));
Nils Diewaldf399a672013-11-18 17:55:22 +0000110 };
111
Nils Diewaldfe6a3652015-02-05 20:34:27 +0000112
113 /**
114 * Get the date as an integer with floored values for
115 * undefined date segments.
Nils Diewaldbb33da22015-03-04 16:24:25 +0000116 *
Nils Diewaldfe6a3652015-02-05 20:34:27 +0000117 * <blockquote><pre>
Nils Diewaldbb33da22015-03-04 16:24:25 +0000118 * KrillDate kd = new KrillDate("2005-06");
119 * System.err.println(kd.floor());
120 * // 20050600
Nils Diewaldfe6a3652015-02-05 20:34:27 +0000121 * </pre></blockquote>
Nils Diewaldbb33da22015-03-04 16:24:25 +0000122 *
Nils Diewaldfe6a3652015-02-05 20:34:27 +0000123 * @return floored integer value.
124 */
Nils Diewaldf399a672013-11-18 17:55:22 +0000125 public int floor () {
Nils Diewaldfe6a3652015-02-05 20:34:27 +0000126 int floor = 0;
127 if (this.year == 0)
128 return 0;
129
130 floor = this.year * 10_000;
131
132 if (this.month == 0)
133 return floor;
134
135 floor += this.month * 100;
136
137 if (this.day == 0)
138 return floor;
139
140 return (floor + this.day);
Nils Diewaldf399a672013-11-18 17:55:22 +0000141 };
142
143
Nils Diewaldfe6a3652015-02-05 20:34:27 +0000144 /**
145 * Serialize date to string, appended by zeros,
146 * in the form of &quot;20050300&quot;.
Nils Diewaldbb33da22015-03-04 16:24:25 +0000147 *
Nils Diewaldfe6a3652015-02-05 20:34:27 +0000148 * @return The date as a string.
149 */
Nils Diewaldbb33da22015-03-04 16:24:25 +0000150 public String toString () {
Nils Diewaldfe6a3652015-02-05 20:34:27 +0000151 StringBuilder sb = this.toStringBuilder();
152 if (sb.length() < 4)
153 return null;
Nils Diewaldf399a672013-11-18 17:55:22 +0000154
Nils Diewaldfe6a3652015-02-05 20:34:27 +0000155 if (sb.length() < 8) {
156 sb.append("00");
157 if (sb.length() < 8) {
158 sb.append("00");
159 };
160 };
Nils Diewaldf399a672013-11-18 17:55:22 +0000161
Nils Diewaldfe6a3652015-02-05 20:34:27 +0000162 return sb.toString();
Nils Diewaldf399a672013-11-18 17:55:22 +0000163 };
164
Nils Diewaldf399a672013-11-18 17:55:22 +0000165
Nils Diewaldfe6a3652015-02-05 20:34:27 +0000166 /**
167 * Serialize ceiled date to string.
Nils Diewaldbb33da22015-03-04 16:24:25 +0000168 *
Nils Diewaldfe6a3652015-02-05 20:34:27 +0000169 * @return The date as a string.
170 */
Nils Diewaldbb33da22015-03-04 16:24:25 +0000171 public String toCeilString () {
Nils Diewaldfe6a3652015-02-05 20:34:27 +0000172 StringBuilder sb = new StringBuilder();
173 return sb.append(this.ceil()).toString();
Nils Diewaldf399a672013-11-18 17:55:22 +0000174 };
175
Nils Diewaldfe6a3652015-02-05 20:34:27 +0000176
177 /**
178 * Serialize floored date to string.
Nils Diewaldbb33da22015-03-04 16:24:25 +0000179 *
Nils Diewaldfe6a3652015-02-05 20:34:27 +0000180 * @return The date as a string.
181 */
Nils Diewaldbb33da22015-03-04 16:24:25 +0000182 public String toFloorString () {
Nils Diewaldfe6a3652015-02-05 20:34:27 +0000183 StringBuilder sb = new StringBuilder();
184 return sb.append(this.floor()).toString();
Nils Diewaldf399a672013-11-18 17:55:22 +0000185 };
186
Nils Diewaldfe6a3652015-02-05 20:34:27 +0000187
188 /**
189 * Serialize date to displayable string.
190 * See format description in the class description.
Nils Diewaldbb33da22015-03-04 16:24:25 +0000191 *
Nils Diewaldfe6a3652015-02-05 20:34:27 +0000192 * @return The date as a string.
193 */
Nils Diewaldbb33da22015-03-04 16:24:25 +0000194 public String toDisplay () {
Nils Diewaldfe6a3652015-02-05 20:34:27 +0000195 StringBuilder sb = this.toStringBuilder();
196 if (sb.length() == 8)
197 sb.insert(6, '-');
198
199 if (sb.length() > 4)
200 sb.insert(4, '-');
201
202 return sb.toString();
203 };
204
205
206
Nils Diewaldf399a672013-11-18 17:55:22 +0000207 // Format date as yyyymmdd
208 private StringBuilder toStringBuilder () {
Nils Diewaldfe6a3652015-02-05 20:34:27 +0000209 StringBuilder sb = new StringBuilder();
Nils Diewaldf399a672013-11-18 17:55:22 +0000210
Nils Diewaldfe6a3652015-02-05 20:34:27 +0000211 if (this.year != 0) {
Nils Diewaldf399a672013-11-18 17:55:22 +0000212
Nils Diewaldfe6a3652015-02-05 20:34:27 +0000213 // Append year
214 if (this.year < 100)
215 sb.append("20");
216
217 sb.append(this.year);
Nils Diewaldbb33da22015-03-04 16:24:25 +0000218
Nils Diewaldfe6a3652015-02-05 20:34:27 +0000219 if (this.month != 0) {
Nils Diewaldbb33da22015-03-04 16:24:25 +0000220
Nils Diewaldfe6a3652015-02-05 20:34:27 +0000221 // Append month
222 if (this.month < 10)
223 sb.append('0');
Nils Diewaldf399a672013-11-18 17:55:22 +0000224
Nils Diewaldfe6a3652015-02-05 20:34:27 +0000225 sb.append(this.month);
Nils Diewaldf399a672013-11-18 17:55:22 +0000226
Nils Diewaldfe6a3652015-02-05 20:34:27 +0000227 if (this.day != 0) {
228 // Append month
229 if (this.day < 10)
230 sb.append('0');
231
232 sb.append(this.day);
233 };
234 };
235 };
236 return sb;
237 };
238
239
240 // Ceil method
241 private static int ceil (byte padding, int nr) {
242 if (nr == 0) {
243 if (padding == (byte) 4)
244 return 9999;
245 else if (padding == (byte) 2)
246 return 99;
247 };
248 return nr;
Nils Diewaldf399a672013-11-18 17:55:22 +0000249 };
250};