
com.actelion.research.util.DateAnalysis Maven / Gradle / Ivy
package com.actelion.research.util;
import java.util.Calendar;
import java.util.GregorianCalendar;
public class DateAnalysis {
private static final String TIME_FORMAT = "\\s\\d\\d:\\d\\d:\\d\\d";
private static final int TIME_FORMAT_LENGTH = 9;
private final int[] max,min,value;
private int day,month,year,currentYear;
private Calendar calendar;
private boolean isTwoDigitYear;
public DateAnalysis() {
value = new int[3];
max = new int[3];
min = new int[3];
min[0] = Integer.MAX_VALUE;
min[1] = Integer.MAX_VALUE;
min[2] = Integer.MAX_VALUE;
day = -1;
month = -1;
year = -1;
isTwoDigitYear = false;
currentYear = new GregorianCalendar().get(Calendar.YEAR);
}
/**
* Checks, whether entry consists of three elements separated by one or more non-word characters
* (neither digit nor letter) that might be day, month and year.
* @param entry
* @return false if entry cannot be a date
*/
public boolean analyse(String entry) {
if (endsWithTime(entry))
entry = entry.substring(0, entry.length() - TIME_FORMAT_LENGTH);
if (!interpreteValues(entry))
return false;
for (int i=0; i<3; i++) {
if (min[i] > value[i])
min[i] = value[i];
if (max[i] < value[i])
max[i] = value[i];
}
return true;
}
private boolean interpreteValues(String entry) {
String[] item = entry.split("[^\\w]+");
if (item.length != 3)
return false;
for (int i=0; i<3; i++) {
value[i] = interprete(item[i], i);
if (value[i] < 0 || value[i] > 3000)
return false;
}
return true;
}
/**
* Call this only once after calling analyse() once or multiple times.
* If this method returns true, then you can use this object to interpret
* date strings of same format with getDateMillis(), e.g. the one passed
* with analyse().
* @return
*/
public boolean isConclusive() {
for (int i=0; i<3; i++) {
if (max[i] > 31 || min[i] == 0) {
if (year != -1 && year != i)
return false;
year = i;
}
}
// if there is no obvious year, we may have a 2-digit year as third of three entries
if (year == -1) {
if (max[2] < 100
&& ((max[0] <= 12 && max[1] <= 31)
|| (max[0] <= 31 && max[1] <= 12))) {
year = 2;
isTwoDigitYear = true;
}
}
for (int i=0; i<3; i++) {
if (i != year && (max[i] > 12 || (month != -1 && month != i))) {
if (day != -1 && day != i)
return false;
day = i;
}
}
for (int i=0; i<3; i++) {
if (i != year && i != day) {
if (month != -1 && month != i)
return false;
month = i;
}
}
if (day == -1 || month == -1 || year == -1)
return false;
calendar = Calendar.getInstance();
return true;
}
public long getDateMillis(String entry) {
int hour = 12;
int minute = 0;
int second = 0;
if (endsWithTime(entry)) {
int index = entry.length()-TIME_FORMAT_LENGTH;
hour = Integer.parseInt(entry.substring(index + 1, index + 3));
minute = Integer.parseInt(entry.substring(index + 4, index + 6));
second = Integer.parseInt(entry.substring(index + 7, index + 9));
entry = entry.substring(0, entry.length() - TIME_FORMAT_LENGTH);
}
if (!interpreteValues(entry))
return -1;
if (isTwoDigitYear)
value[year] += (value[year] <= currentYear) ? 2000 : 1900;
calendar.set(value[year], value[month]-1, value[day], hour, minute, second);
return calendar.getTimeInMillis();
}
public float getDateFloat(String entry) {
long millis = getDateMillis(entry);
return millis == -1L ? Float.NaN : (float)((millis+43200000L)/86400000L);
}
private int interprete(String item, int index) {
try {
return Integer.parseInt(item);
}
catch (Exception e) {
int value = interpreteMonth(item);
if (value != -1) {
if (month != -1 && month != index)
return -1; // month found in different positions
month = index;
}
return value;
}
}
public static int interpreteMonth(String item) {
item = item.toLowerCase();
if (item.startsWith("jan"))
return 1;
if (item.startsWith("feb"))
return 2;
if (item.startsWith("mar") || item.startsWith("mär") || item.startsWith("mae"))
return 3;
if (item.startsWith("apr"))
return 4;
if (item.startsWith("may") || item.startsWith("mai"))
return 5;
if (item.startsWith("jun"))
return 6;
if (item.startsWith("jul"))
return 7;
if (item.startsWith("aug"))
return 8;
if (item.startsWith("sep"))
return 9;
if (item.startsWith("oct") || item.startsWith("okt"))
return 10;
if (item.startsWith("nov"))
return 11;
if (item.startsWith("dec") || item.startsWith("dez"))
return 12;
return -1;
}
private boolean endsWithTime(String entry) {
return entry != null
&& entry.length() > TIME_FORMAT_LENGTH
&& entry.substring(entry.length()-TIME_FORMAT_LENGTH).matches(TIME_FORMAT);
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy