Project

General

Profile

1
package eu.dnetlib.functionality.index.model;
2

    
3
import java.text.DateFormat;
4
import java.text.ParseException;
5
import java.text.SimpleDateFormat;
6
import java.util.Date;
7
import java.util.TimeZone;
8
import java.util.regex.Pattern;
9

    
10
/**
11
 * helper class for formatting and parsing Values. all methods synchronize on the used local formatter object, so you
12
 * can use the shared instance. Using multiple instances may improve performance, though, because of less
13
 * synchronization.
14
 */
15
public class ValueFormatHelper {
16
	/** shared global helper instance. */
17
	public static final ValueFormatHelper INSTANCE = new ValueFormatHelper();
18

    
19
	/** The max. length of strings to be parsed as date. */
20
	private static final int DATE_LENGTH = 10;
21

    
22
	/** The length of strings to be parsed as date time for (default) pattern 1. */
23
	private static final int DATE_TIME_LENGTH_PATTERN_DEFAULT = 28;
24

    
25
	/** The length of strings to be parsed as date time for pattern 2 and 3. */
26
	private static final int DATE_TIME_LENGTH_PATTERN_2_AND_3 = 24;
27

    
28
	/** The length of strings to be parsed as date time for pattern 4. */
29
	private static final int DATE_TIME_LENGTH_PATTERN_4 = 20;
30

    
31
	/** formatter to create and parse standard string representations of Date values: "yyyy-MM-dd". */
32
	private final DateFormat _formatDate = new SimpleDateFormat("yyyy-MM-dd");
33

    
34
	/** valid Datetime value pattern with milliseconds and time zone (default for printing). */
35
	private final DateFormat _formatDateTimePatternDefault = getDefaultDateTimeFormat();
36

    
37
	/** valid Datetime value pattern with time zone. */
38
	private final DateFormat _formatDateTimePattern2 = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ssZ");
39

    
40
	/** valid Datetime value pattern with milliseconds and time zone 'Z' (UTC). */
41
	private final DateFormat _formatDateTimePattern3 = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS'Z'");
42

    
43
	/** valid Datetime value pattern without milliseconds and time zone 'Z' (UTC). */
44
	private final DateFormat _formatDateTimePattern4 = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss'Z'");
45

    
46
	/** pattern for checking if the string might be a date. */
47
	private final Pattern _formatPatternDateDefault = Pattern.compile("\\d{4}-\\d{2}-\\d{2}");
48

    
49
	/** pattern for checking if the string might be a date time for default pattern. */
50
	private final Pattern _formatPatternTimeDefault = Pattern.compile("\\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2}:\\d{2}\\.\\d{3}[+-]{1}\\d{4}");
51

    
52
	/** pattern for checking if the string might be a date time for pattern 2. */
53
	private final Pattern _formatPatternTime2 = Pattern.compile("\\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2}:\\d{2}[+-]{1}\\d{4}");
54

    
55
	/** pattern for checking if the string might be a date time for pattern 3. */
56
	private final Pattern _formatPatternTime3 = Pattern.compile("\\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2}:\\d{2}\\.\\d{3}Z");
57

    
58
	/** pattern for checking if the string might be a date time for pattern 4. */
59
	private final Pattern _formatPatternTime4 = Pattern.compile("\\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2}:\\d{2}Z");
60

    
61
	/**
62
	 * create local instance.
63
	 */
64
	public ValueFormatHelper() {
65
		_formatDate.setLenient(false);
66
		_formatDateTimePatternDefault.setLenient(false);
67
		_formatDateTimePattern2.setLenient(false);
68
		_formatDateTimePattern3.setLenient(false);
69
		_formatDateTimePattern3.setTimeZone(TimeZone.getTimeZone("UTC"));
70
		_formatDateTimePattern4.setLenient(false);
71
		_formatDateTimePattern4.setTimeZone(TimeZone.getTimeZone("UTC"));
72
	}
73

    
74
	/**
75
	 * @return the default format for datetime values.
76
	 */
77
	public static SimpleDateFormat getDefaultDateTimeFormat() {
78
		final SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSSZ");
79
		sdf.setLenient(false);
80
		return sdf;
81
	}
82

    
83
	/**
84
	 * format value as Date string.
85
	 * 
86
	 * @param value
87
	 *            a date value
88
	 * @return formatted date.
89
	 */
90
	public String formatDate(final Date value) {
91
		synchronized (_formatDate) {
92
			return _formatDate.format(value);
93
		}
94
	}
95

    
96
	/**
97
	 * format value as DateTime string.
98
	 * 
99
	 * @param value
100
	 *            a datetime value
101
	 * @return formatted datetime string
102
	 */
103
	public String formatDateTime(final Date value) {
104
		synchronized (_formatDateTimePatternDefault) {
105
			return _formatDateTimePatternDefault.format(value);
106
		}
107
	}
108

    
109
	/**
110
	 * parse a date string.
111
	 * 
112
	 * @param dateString
113
	 *            a date string
114
	 * @return parsed Date
115
	 * @throws ParseException
116
	 *             string has wrong format
117
	 */
118
	public Date parseDate(final String dateString) throws ParseException {
119
		if (dateString.length() == DATE_LENGTH && _formatPatternDateDefault.matcher(dateString).matches()) {
120
			synchronized (_formatDate) {
121
				return _formatDate.parse(dateString);
122
			}
123
		} else {
124
			throw new ParseException("Length of date string '" + dateString + "' exceeds maximum date length of " + DATE_LENGTH, DATE_LENGTH);
125
		}
126
	}
127

    
128
	/**
129
	 * parse a date string.
130
	 * 
131
	 * @param dateString
132
	 *            a date string
133
	 * @return parsed Date if correct format, else null.
134
	 */
135
	public Date tryParseDate(final String dateString) {
136
		if (dateString.length() == DATE_LENGTH && _formatPatternDateDefault.matcher(dateString).matches()) {
137
			synchronized (_formatDate) {
138
				try {
139
					return _formatDate.parse(dateString);
140
				} catch (final ParseException ex) {
141
					; // not a date ... fine.
142
				}
143
			}
144
		}
145
		return null;
146
	}
147

    
148
	/**
149
	 * parse datetime string.
150
	 * 
151
	 * @param dateTimeString
152
	 *            a datetime string
153
	 * @return parsed Date
154
	 * @throws ParseException
155
	 *             string has wrong format
156
	 */
157
	public Date parseDateTime(final String dateTimeString) throws ParseException {
158
		final Date result;
159
		final int dateLen = dateTimeString.length();
160
		if (dateLen == DATE_TIME_LENGTH_PATTERN_DEFAULT && _formatPatternTimeDefault.matcher(dateTimeString).matches()) {
161
			synchronized (_formatDateTimePatternDefault) {
162
				result = _formatDateTimePatternDefault.parse(dateTimeString);
163
			}
164
		} else if (dateLen == DATE_TIME_LENGTH_PATTERN_2_AND_3 && _formatPatternTime2.matcher(dateTimeString).matches()) {
165
			synchronized (_formatDateTimePattern2) {
166
				result = _formatDateTimePattern2.parse(dateTimeString);
167
			}
168
		} else if (dateLen == DATE_TIME_LENGTH_PATTERN_2_AND_3 && _formatPatternTime3.matcher(dateTimeString).matches()) {
169
			synchronized (_formatDateTimePattern3) {
170
				result = _formatDateTimePattern3.parse(dateTimeString);
171
			}
172
		} else if (dateLen == DATE_TIME_LENGTH_PATTERN_4 && _formatPatternTime4.matcher(dateTimeString).matches()) {
173
			synchronized (_formatDateTimePattern4) {
174
				result = _formatDateTimePattern4.parse(dateTimeString);
175
			}
176
		} else {
177
			throw new ParseException("Length '" + dateTimeString.length() + "' of datetime string '" + dateTimeString
178
					+ "' doesn't match expected pattern length", dateTimeString.length());
179
		}
180
		return result;
181
	}
182

    
183
	/**
184
	 * parse datetime string.
185
	 * 
186
	 * @param dateTimeString
187
	 *            a datetime string
188
	 * @return parsed Date if correct format, else null;
189
	 */
190
	public Date tryParseDateTime(final String dateTimeString) {
191
		Date result = null;
192
		try {
193
			switch (dateTimeString.length()) {
194
			case DATE_TIME_LENGTH_PATTERN_DEFAULT:
195
				if (_formatPatternTimeDefault.matcher(dateTimeString).matches()) {
196
					synchronized (_formatDateTimePatternDefault) {
197
						result = _formatDateTimePatternDefault.parse(dateTimeString);
198
					}
199
				}
200
				break;
201
			case DATE_TIME_LENGTH_PATTERN_2_AND_3:
202
				if (_formatPatternTime2.matcher(dateTimeString).matches()) {
203
					synchronized (_formatDateTimePattern2) {
204
						result = _formatDateTimePattern2.parse(dateTimeString);
205
					}
206
				} else if (_formatPatternTime3.matcher(dateTimeString).matches()) {
207
					synchronized (_formatDateTimePattern3) {
208
						result = _formatDateTimePattern3.parse(dateTimeString);
209
					}
210
				}
211
				break;
212
			case DATE_TIME_LENGTH_PATTERN_4:
213
				if (_formatPatternTime4.matcher(dateTimeString).matches()) {
214
					synchronized (_formatDateTimePattern4) {
215
						result = _formatDateTimePattern4.parse(dateTimeString);
216
					}
217
				}
218
				break;
219
			default:
220
				break;
221
			}
222
		} catch (final ParseException ex) {
223
			; // not a datetime ... fine.
224
		}
225
		return result;
226
	}
227
}
(8-8/8)