| Nils Diewald | f399a67 | 2013-11-18 17:55:22 +0000 | [diff] [blame] | 1 | package de.ids_mannheim.korap.util; |
| 2 | |||||
| 3 | import java.util.*; | ||||
| 4 | import java.util.regex.*; | ||||
| 5 | |||||
| 6 | /** | ||||
| Nils Diewald | c383ed0 | 2015-02-26 21:35:22 +0000 | [diff] [blame] | 7 | * KrillDate implements a helper object to stringify |
| Nils Diewald | fe6a365 | 2015-02-05 20:34:27 +0000 | [diff] [blame] | 8 | * and parse date strings optimized |
| 9 | * for integer range queries in Lucene. | ||||
| 10 | * No support for b.c. dates. | ||||
| Nils Diewald | bb33da2 | 2015-03-04 16:24:25 +0000 | [diff] [blame] | 11 | * |
| 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 Diewald | fe6a365 | 2015-02-05 20:34:27 +0000 | [diff] [blame] | 17 | * <blockquote><pre> |
| Nils Diewald | bb33da2 | 2015-03-04 16:24:25 +0000 | [diff] [blame] | 18 | * 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 Diewald | fe6a365 | 2015-02-05 20:34:27 +0000 | [diff] [blame] | 25 | * </pre></blockquote> |
| Nils Diewald | bb33da2 | 2015-03-04 16:24:25 +0000 | [diff] [blame] | 26 | * |
| Nils Diewald | fe6a365 | 2015-02-05 20:34:27 +0000 | [diff] [blame] | 27 | * @author diewald |
| Nils Diewald | f399a67 | 2013-11-18 17:55:22 +0000 | [diff] [blame] | 28 | */ |
| Nils Diewald | c383ed0 | 2015-02-26 21:35:22 +0000 | [diff] [blame] | 29 | public class KrillDate { |
| Nils Diewald | f399a67 | 2013-11-18 17:55:22 +0000 | [diff] [blame] | 30 | |
| Nils Diewald | fe6a365 | 2015-02-05 20:34:27 +0000 | [diff] [blame] | 31 | /** |
| 32 | * The year of the date. | ||||
| 33 | */ | ||||
| 34 | public int year = 0; | ||||
| Nils Diewald | f399a67 | 2013-11-18 17:55:22 +0000 | [diff] [blame] | 35 | |
| Nils Diewald | fe6a365 | 2015-02-05 20:34:27 +0000 | [diff] [blame] | 36 | |
| 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 Diewald | bb33da2 | 2015-03-04 16:24:25 +0000 | [diff] [blame] | 50 | private static final Pattern datePattern = Pattern |
| 51 | .compile("\\s*(\\d\\d\\d\\d)" + "(?:\\s*[-/]?\\s*(\\d\\d)" | ||||
| 52 | + "(?:\\s*[-/]?\\s*(\\d\\d))?)?\\s*"); | ||||
| Nils Diewald | f399a67 | 2013-11-18 17:55:22 +0000 | [diff] [blame] | 53 | |
| Nils Diewald | fe6a365 | 2015-02-05 20:34:27 +0000 | [diff] [blame] | 54 | /** |
| 55 | * Static value representing the minimum date. | ||||
| 56 | */ | ||||
| 57 | public static final int BEGINNING = 0; | ||||
| Nils Diewald | f399a67 | 2013-11-18 17:55:22 +0000 | [diff] [blame] | 58 | |
| Nils Diewald | f399a67 | 2013-11-18 17:55:22 +0000 | [diff] [blame] | 59 | |
| Nils Diewald | fe6a365 | 2015-02-05 20:34:27 +0000 | [diff] [blame] | 60 | /** |
| 61 | * Static value representing the maximum date. | ||||
| 62 | */ | ||||
| 63 | public static final int END = 99_999_999; | ||||
| 64 | |||||
| 65 | |||||
| 66 | /** | ||||
| Nils Diewald | c383ed0 | 2015-02-26 21:35:22 +0000 | [diff] [blame] | 67 | * Construct a new KrillDate object. |
| Nils Diewald | fe6a365 | 2015-02-05 20:34:27 +0000 | [diff] [blame] | 68 | */ |
| Nils Diewald | bb33da2 | 2015-03-04 16:24:25 +0000 | [diff] [blame] | 69 | public KrillDate () {}; |
| Nils Diewald | fe6a365 | 2015-02-05 20:34:27 +0000 | [diff] [blame] | 70 | |
| 71 | |||||
| 72 | /** | ||||
| Nils Diewald | c383ed0 | 2015-02-26 21:35:22 +0000 | [diff] [blame] | 73 | * Construct a new KrillDate object. |
| Nils Diewald | bb33da2 | 2015-03-04 16:24:25 +0000 | [diff] [blame] | 74 | * |
| 75 | * @param date | ||||
| 76 | * The date as a string (see synopsis). | ||||
| Nils Diewald | fe6a365 | 2015-02-05 20:34:27 +0000 | [diff] [blame] | 77 | */ |
| Nils Diewald | c383ed0 | 2015-02-26 21:35:22 +0000 | [diff] [blame] | 78 | public KrillDate (String date) { |
| Nils Diewald | fe6a365 | 2015-02-05 20:34:27 +0000 | [diff] [blame] | 79 | 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 Diewald | bb33da2 | 2015-03-04 16:24:25 +0000 | [diff] [blame] | 89 | this.day = Integer.parseInt(m.group(3)); |
| Nils Diewald | fe6a365 | 2015-02-05 20:34:27 +0000 | [diff] [blame] | 90 | }; |
| Nils Diewald | f399a67 | 2013-11-18 17:55:22 +0000 | [diff] [blame] | 91 | }; |
| 92 | |||||
| Nils Diewald | f399a67 | 2013-11-18 17:55:22 +0000 | [diff] [blame] | 93 | |
| Nils Diewald | fe6a365 | 2015-02-05 20:34:27 +0000 | [diff] [blame] | 94 | /** |
| 95 | * Get the date as an integer with ceiled values for | ||||
| 96 | * undefined date segments. | ||||
| Nils Diewald | bb33da2 | 2015-03-04 16:24:25 +0000 | [diff] [blame] | 97 | * |
| Nils Diewald | fe6a365 | 2015-02-05 20:34:27 +0000 | [diff] [blame] | 98 | * <blockquote><pre> |
| Nils Diewald | bb33da2 | 2015-03-04 16:24:25 +0000 | [diff] [blame] | 99 | * KrillDate kd = new KrillDate("2005-06"); |
| 100 | * System.err.println(kd.ceil()); | ||||
| 101 | * // 20050699 | ||||
| Nils Diewald | fe6a365 | 2015-02-05 20:34:27 +0000 | [diff] [blame] | 102 | * </pre></blockquote> |
| Nils Diewald | bb33da2 | 2015-03-04 16:24:25 +0000 | [diff] [blame] | 103 | * |
| Nils Diewald | fe6a365 | 2015-02-05 20:34:27 +0000 | [diff] [blame] | 104 | * @return ceiled integer value. |
| 105 | */ | ||||
| Nils Diewald | f399a67 | 2013-11-18 17:55:22 +0000 | [diff] [blame] | 106 | public int ceil () { |
| Nils Diewald | bb33da2 | 2015-03-04 16:24:25 +0000 | [diff] [blame] | 107 | return (ceil((byte) 4, this.year) * 10_000) |
| 108 | + (ceil((byte) 2, this.month) * 100) | ||||
| 109 | + (ceil((byte) 2, this.day)); | ||||
| Nils Diewald | f399a67 | 2013-11-18 17:55:22 +0000 | [diff] [blame] | 110 | }; |
| 111 | |||||
| Nils Diewald | fe6a365 | 2015-02-05 20:34:27 +0000 | [diff] [blame] | 112 | |
| 113 | /** | ||||
| 114 | * Get the date as an integer with floored values for | ||||
| 115 | * undefined date segments. | ||||
| Nils Diewald | bb33da2 | 2015-03-04 16:24:25 +0000 | [diff] [blame] | 116 | * |
| Nils Diewald | fe6a365 | 2015-02-05 20:34:27 +0000 | [diff] [blame] | 117 | * <blockquote><pre> |
| Nils Diewald | bb33da2 | 2015-03-04 16:24:25 +0000 | [diff] [blame] | 118 | * KrillDate kd = new KrillDate("2005-06"); |
| 119 | * System.err.println(kd.floor()); | ||||
| 120 | * // 20050600 | ||||
| Nils Diewald | fe6a365 | 2015-02-05 20:34:27 +0000 | [diff] [blame] | 121 | * </pre></blockquote> |
| Nils Diewald | bb33da2 | 2015-03-04 16:24:25 +0000 | [diff] [blame] | 122 | * |
| Nils Diewald | fe6a365 | 2015-02-05 20:34:27 +0000 | [diff] [blame] | 123 | * @return floored integer value. |
| 124 | */ | ||||
| Nils Diewald | f399a67 | 2013-11-18 17:55:22 +0000 | [diff] [blame] | 125 | public int floor () { |
| Nils Diewald | fe6a365 | 2015-02-05 20:34:27 +0000 | [diff] [blame] | 126 | 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 Diewald | f399a67 | 2013-11-18 17:55:22 +0000 | [diff] [blame] | 141 | }; |
| 142 | |||||
| 143 | |||||
| Nils Diewald | fe6a365 | 2015-02-05 20:34:27 +0000 | [diff] [blame] | 144 | /** |
| 145 | * Serialize date to string, appended by zeros, | ||||
| 146 | * in the form of "20050300". | ||||
| Nils Diewald | bb33da2 | 2015-03-04 16:24:25 +0000 | [diff] [blame] | 147 | * |
| Nils Diewald | fe6a365 | 2015-02-05 20:34:27 +0000 | [diff] [blame] | 148 | * @return The date as a string. |
| 149 | */ | ||||
| Nils Diewald | bb33da2 | 2015-03-04 16:24:25 +0000 | [diff] [blame] | 150 | public String toString () { |
| Nils Diewald | fe6a365 | 2015-02-05 20:34:27 +0000 | [diff] [blame] | 151 | StringBuilder sb = this.toStringBuilder(); |
| 152 | if (sb.length() < 4) | ||||
| 153 | return null; | ||||
| Nils Diewald | f399a67 | 2013-11-18 17:55:22 +0000 | [diff] [blame] | 154 | |
| Nils Diewald | fe6a365 | 2015-02-05 20:34:27 +0000 | [diff] [blame] | 155 | if (sb.length() < 8) { |
| 156 | sb.append("00"); | ||||
| 157 | if (sb.length() < 8) { | ||||
| 158 | sb.append("00"); | ||||
| 159 | }; | ||||
| 160 | }; | ||||
| Nils Diewald | f399a67 | 2013-11-18 17:55:22 +0000 | [diff] [blame] | 161 | |
| Nils Diewald | fe6a365 | 2015-02-05 20:34:27 +0000 | [diff] [blame] | 162 | return sb.toString(); |
| Nils Diewald | f399a67 | 2013-11-18 17:55:22 +0000 | [diff] [blame] | 163 | }; |
| 164 | |||||
| Nils Diewald | f399a67 | 2013-11-18 17:55:22 +0000 | [diff] [blame] | 165 | |
| Nils Diewald | fe6a365 | 2015-02-05 20:34:27 +0000 | [diff] [blame] | 166 | /** |
| 167 | * Serialize ceiled date to string. | ||||
| Nils Diewald | bb33da2 | 2015-03-04 16:24:25 +0000 | [diff] [blame] | 168 | * |
| Nils Diewald | fe6a365 | 2015-02-05 20:34:27 +0000 | [diff] [blame] | 169 | * @return The date as a string. |
| 170 | */ | ||||
| Nils Diewald | bb33da2 | 2015-03-04 16:24:25 +0000 | [diff] [blame] | 171 | public String toCeilString () { |
| Nils Diewald | fe6a365 | 2015-02-05 20:34:27 +0000 | [diff] [blame] | 172 | StringBuilder sb = new StringBuilder(); |
| 173 | return sb.append(this.ceil()).toString(); | ||||
| Nils Diewald | f399a67 | 2013-11-18 17:55:22 +0000 | [diff] [blame] | 174 | }; |
| 175 | |||||
| Nils Diewald | fe6a365 | 2015-02-05 20:34:27 +0000 | [diff] [blame] | 176 | |
| 177 | /** | ||||
| 178 | * Serialize floored date to string. | ||||
| Nils Diewald | bb33da2 | 2015-03-04 16:24:25 +0000 | [diff] [blame] | 179 | * |
| Nils Diewald | fe6a365 | 2015-02-05 20:34:27 +0000 | [diff] [blame] | 180 | * @return The date as a string. |
| 181 | */ | ||||
| Nils Diewald | bb33da2 | 2015-03-04 16:24:25 +0000 | [diff] [blame] | 182 | public String toFloorString () { |
| Nils Diewald | fe6a365 | 2015-02-05 20:34:27 +0000 | [diff] [blame] | 183 | StringBuilder sb = new StringBuilder(); |
| 184 | return sb.append(this.floor()).toString(); | ||||
| Nils Diewald | f399a67 | 2013-11-18 17:55:22 +0000 | [diff] [blame] | 185 | }; |
| 186 | |||||
| Nils Diewald | fe6a365 | 2015-02-05 20:34:27 +0000 | [diff] [blame] | 187 | |
| 188 | /** | ||||
| 189 | * Serialize date to displayable string. | ||||
| 190 | * See format description in the class description. | ||||
| Nils Diewald | bb33da2 | 2015-03-04 16:24:25 +0000 | [diff] [blame] | 191 | * |
| Nils Diewald | fe6a365 | 2015-02-05 20:34:27 +0000 | [diff] [blame] | 192 | * @return The date as a string. |
| 193 | */ | ||||
| Nils Diewald | bb33da2 | 2015-03-04 16:24:25 +0000 | [diff] [blame] | 194 | public String toDisplay () { |
| Nils Diewald | fe6a365 | 2015-02-05 20:34:27 +0000 | [diff] [blame] | 195 | 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 Diewald | f399a67 | 2013-11-18 17:55:22 +0000 | [diff] [blame] | 207 | // Format date as yyyymmdd |
| 208 | private StringBuilder toStringBuilder () { | ||||
| Nils Diewald | fe6a365 | 2015-02-05 20:34:27 +0000 | [diff] [blame] | 209 | StringBuilder sb = new StringBuilder(); |
| Nils Diewald | f399a67 | 2013-11-18 17:55:22 +0000 | [diff] [blame] | 210 | |
| Nils Diewald | fe6a365 | 2015-02-05 20:34:27 +0000 | [diff] [blame] | 211 | if (this.year != 0) { |
| Nils Diewald | f399a67 | 2013-11-18 17:55:22 +0000 | [diff] [blame] | 212 | |
| Nils Diewald | fe6a365 | 2015-02-05 20:34:27 +0000 | [diff] [blame] | 213 | // Append year |
| 214 | if (this.year < 100) | ||||
| 215 | sb.append("20"); | ||||
| 216 | |||||
| 217 | sb.append(this.year); | ||||
| Nils Diewald | bb33da2 | 2015-03-04 16:24:25 +0000 | [diff] [blame] | 218 | |
| Nils Diewald | fe6a365 | 2015-02-05 20:34:27 +0000 | [diff] [blame] | 219 | if (this.month != 0) { |
| Nils Diewald | bb33da2 | 2015-03-04 16:24:25 +0000 | [diff] [blame] | 220 | |
| Nils Diewald | fe6a365 | 2015-02-05 20:34:27 +0000 | [diff] [blame] | 221 | // Append month |
| 222 | if (this.month < 10) | ||||
| 223 | sb.append('0'); | ||||
| Nils Diewald | f399a67 | 2013-11-18 17:55:22 +0000 | [diff] [blame] | 224 | |
| Nils Diewald | fe6a365 | 2015-02-05 20:34:27 +0000 | [diff] [blame] | 225 | sb.append(this.month); |
| Nils Diewald | f399a67 | 2013-11-18 17:55:22 +0000 | [diff] [blame] | 226 | |
| Nils Diewald | fe6a365 | 2015-02-05 20:34:27 +0000 | [diff] [blame] | 227 | 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 Diewald | f399a67 | 2013-11-18 17:55:22 +0000 | [diff] [blame] | 249 | }; |
| 250 | }; | ||||