com.actelion.research.util.DateAnalysis Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of openchemlib Show documentation
Show all versions of openchemlib Show documentation
Open Source Chemistry Library
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);
}
}