package mediawiki.info.wikibase;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.GregorianCalendar;
import java.util.Locale;
import java.util.TimeZone;
public class WikibaseDate {
static {
Locale.setDefault(Locale.GERMANY);
}
public final static int ONE_BILLION_YEARS = 0;
public final static int HUNDRET_MILLION_YEARS = 1;
public final static int TEN_MILLION_YEARS = 2;
public final static int ONE_MILLION_YEARS = 3;
public final static int HUNDRET_THOUSAND_YEARS = 4;
public final static int TEN_THOUSAND_YEARS = 5;
public final static int ONE_THOUSAND_YEARS = 6;
public final static int ONE_HUNDRET_YEARS = 7;
public final static int TEN_YEARS = 8;
public final static int ONE_YEAR = 9;
public final static int ONE_MONTH = 10;
public final static int ONE_DAY = 11;
public final static int ONE_HOUR = 12;
public final static int ONE_MINUTE = 13;
public final static int ONE_SECOND = 14;
private Date date = null;
private int timezone;
private int before;
private int after;
private int precision;
private String calendarmodel;
public WikibaseDate(int precision){
this(new Date(),TimeZone.getDefault().getRawOffset()/1000/60,0,0,precision);
}
public WikibaseDate(Date date, int tz, int before, int after, int precision, String calendarmodel){
setDate(date);
setTimezone(tz);
setBefore(before);
setAfter(after);
setPrecision(precision);
setCalendarmodel(calendarmodel);
}
public WikibaseDate(Date date, int tz, int before, int after, int precision){
this(date,tz,before,after,precision,"http://www.wikidata.org/entity/Q1985727");
}
public WikibaseDate(String date, int tz, int before, int after, int precision, String calendarmodel) throws ParseException{
this(new Date(),tz,before,after,precision,calendarmodel);
switch(date.charAt(0)){
case '+' : date = "AD"+date.substring(1); break;
case '-' : date = "BC"+date.substring(1); break;
}
if(precision <= ONE_YEAR)
date = date.replaceAll("\\-00\\-00T", "-01-01T");
SimpleDateFormat d = new SimpleDateFormat( "GGyyyyyyyyyyy-MM-dd'T'HH:mm:ss'Z'", Locale.ENGLISH);
if(precision > ONE_DAY){
TimeZone z = (TimeZone) TimeZone.getDefault().clone();
z.setRawOffset(tz*60*1000);
d.setTimeZone(z);
}else{
d.setTimeZone(TimeZone.getTimeZone("UTC"));
}
setDate(d.parse(date));
}
public String getFormattedDate(){
SimpleDateFormat d2 = new SimpleDateFormat( "GGyyyyyyyyyyy-MM-dd'T'", Locale.ENGLISH); // HH:mm:ss'Z'
if(getPrecision() > ONE_DAY){
TimeZone z = (TimeZone) TimeZone.getDefault().clone();
z.setRawOffset(getTimezone()*60*1000);
d2.setTimeZone(z);
}else{
d2.setTimeZone(TimeZone.getTimeZone("UTC"));
}
String d = d2.format(getDate());
switch(d.charAt(0)){
case 'A' : d = "+"+d.substring(8); break;
case 'B' : d = "-"+d.substring(8); break;
}
d = d.replaceAll("^([\\+\\-])0*", "$1");
if(getPrecision() <= ONE_YEAR)
d = d.replaceAll("^([\\+\\-]\\d+)\\-\\d{2}\\-\\d{2}T", "$1-00-00T");
return d+"00:00:00Z"; // TODO support for hours, minutes, seconds
}
public Date getDate() {
return date;
}
public int getTimezone() {
return timezone;
}
public int getBefore() {
return before;
}
public int getAfter() {
return after;
}
public int getPrecision() {
return precision;
}
public String getCalendarmodel() {
return calendarmodel;
}
public void setDate(Date date) {
this.date = date;
}
public void setTimezone(int timezone) {
this.timezone = timezone;
}
public void setBefore(int before) {
this.before = before;
}
public void setAfter(int after) {
this.after = after;
}
public void setPrecision(int precision) {
this.precision = precision;
}
public void setCalendarmodel(String calendarmodel) {
this.calendarmodel = calendarmodel;
}
@Override
public String toString() {
return getFormattedDate();
}
// TODO parseWikipediaDate Fertigstellen
public static WikibaseDate parseWikipediaDate(String date) throws ParseException {
date = date.replaceAll("\\ \\;", " ");
date = date.replaceAll("[\\[\\]]+", "");
date = date.trim();
String months = "Januar|Februar|März|April|Mai|Juni|Juli|August|September|Oktober|November|Dezember";
if(date.matches("[0-9]{1,4}")){
SimpleDateFormat sdf = new SimpleDateFormat("yyyy", Locale.GERMAN);
return new WikibaseDate(sdf.parse(date), 0, 0, 0, ONE_YEAR);
}else if(date.matches("[0-9]{1,4} [nv]{1}\\. Chr\\.")){
SimpleDateFormat sdf = new SimpleDateFormat("yyyy GGGG", Locale.GERMAN);
return new WikibaseDate(sdf.parse(date), 0, 0, 0, ONE_YEAR);
}else if(date.matches("[0-9]{1,2}\\. ("+months+") [0-9]{1,4}")){
String[] ms = months.split("\\|");
for(int i = 0; i < ms.length; i++){
date = date.replaceAll(ms[i], (i+1)+"");
}
SimpleDateFormat sdf = new SimpleDateFormat("dd. MM yyyy", Locale.GERMAN);
return new WikibaseDate(sdf.parse(date), 0, 0, 0, ONE_DAY);
}else if(date.matches("[0-9]{1,2}\\. ("+months+") [0-9]{1,4} [nv]{1}\\. Chr\\.")){
String[] ms = months.split("\\|");
for(int i = 0; i < ms.length; i++){
date = date.replaceAll(ms[i], (i+1)+"");
}
SimpleDateFormat sdf = new SimpleDateFormat("dd. MM yyyy GGGG", Locale.GERMAN);
return new WikibaseDate(sdf.parse(date), 0, 0, 0, ONE_DAY);
}else if(date.matches("[0-9]{1,2}\\. Jahrhundert")){
date = date.replaceAll("\\. Jahrhundert", "00");
SimpleDateFormat sdf = new SimpleDateFormat("yyyy", Locale.GERMAN);
return new WikibaseDate(sdf.parse(date), 0, 0, 0, ONE_HUNDRET_YEARS);
}else if(date.matches("[0-9]{1,2}\\. Jahrhundert [nv]{1}\\. Chr\\.")){
date = date.replaceAll("\\. Jahrhundert", "00");
SimpleDateFormat sdf = new SimpleDateFormat("yyyy GGGG", Locale.GERMAN);
return new WikibaseDate(sdf.parse(date), 0, 0, 0, ONE_HUNDRET_YEARS);
}else if(date.matches("("+months+") [0-9]{1,4}")){
String[] ms = months.split("\\|");
for(int i = 0; i < ms.length; i++){
date = date.replaceAll(ms[i], (i+1)+"");
}
SimpleDateFormat sdf = new SimpleDateFormat("MM yyyy");
return new WikibaseDate(sdf.parse(date), 0, 0, 0, ONE_MONTH);
}else if(date.matches("("+months+") [0-9]{1,4} [nv]{1}\\. Chr\\.")){
String[] ms = months.split("\\|");
for(int i = 0; i < ms.length; i++){
date = date.replaceAll(ms[i], (i+1)+"");
}
SimpleDateFormat sdf = new SimpleDateFormat("MM yyyy GGGG", Locale.GERMAN);
return new WikibaseDate(sdf.parse(date), 0, 0, 0, ONE_MONTH);
}else if(date.matches("[0-9]{1,2}\\. Jahrtausend [nv]{1}\\. Chr\\.")){
date = date.replaceAll("\\. Jahrtausend", "000");
SimpleDateFormat sdf = new SimpleDateFormat("yyyy GGGG", Locale.GERMAN);
return new WikibaseDate(sdf.parse(date), 0, 0, 0, ONE_THOUSAND_YEARS);
}else if(date.matches("[0-9]{1,2}\\.[0-9]{1,2}\\.[0-9]{1,2}")){
SimpleDateFormat sdf = new SimpleDateFormat("dd.MM.yy", Locale.GERMAN);
return new WikibaseDate(sdf.parse(date), 0, 0, 0, ONE_DAY);
}else if(date.matches("[0-9]{1,2}\\.[0-9]{1,2}\\.[0-9]{3,4}")){
SimpleDateFormat sdf = new SimpleDateFormat("dd.MM.yyyy", Locale.GERMAN);
return new WikibaseDate(sdf.parse(date), 0, 0, 0, ONE_DAY);
}else if(date.matches("[0-9]{1,2}\\.[0-9]{1,2}\\.[0-9]{1,2} [nv]{1}\\. Chr\\.")){
SimpleDateFormat sdf = new SimpleDateFormat("dd.MM.yy GGGG", Locale.GERMAN);
return new WikibaseDate(sdf.parse(date), 0, 0, 0, ONE_DAY);
}
throw new ParseException("unknown pattern in "+date, 0);
}
@Override
public boolean equals(Object obj) {
if(obj == null)
return false;
if(!(obj instanceof WikibaseDate))
return false;
WikibaseDate d = (WikibaseDate) obj;
return this.date.equals(d.date)
&& this.timezone == d.timezone
&& this.before == d.before
&& this.after == d.after
&& this.precision == d.precision
&& this.calendarmodel.equals(d.calendarmodel);
}
}