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); } }