package org.simantics.xml.sax.base.datatypes.literal; import java.text.ParseException; import java.text.SimpleDateFormat; import java.util.Calendar; import java.util.Date; import java.util.TimeZone; import org.simantics.databoard.Bindings; import org.simantics.databoard.binding.Binding; import org.simantics.databoard.util.Bean; public class DateTime extends Bean implements org.simantics.xml.sax.base.datatypes.adt.DateTime { public static final Binding BINDING = Bindings.getBindingUnchecked(DateTime.class); public int year; public byte month; public byte day; public byte hours; public byte minutes; public byte seconds; public int offset; public DateTime(){ super(BINDING); } public DateTime(int year, int month, int day, int hours, int minutes, int seconds) { this(year, month, day, hours, minutes, seconds, java.lang.Integer.MIN_VALUE); } public DateTime(int year, int month, int day, int hours, int minutes, int seconds, int offset) { super(BINDING); if (month <= 0 || month > 12) throw new IllegalArgumentException("Month must be between 1 - 12, got " + month); if (day <= 0 || day > 31) throw new IllegalArgumentException("Day must be between 1 - 31, got " + day); if (hours < 0 || hours > 23) throw new IllegalArgumentException("Hours must be between 0 - 23, got " + hours); if (minutes < 0 || minutes > 59) throw new IllegalArgumentException("Minutes must be between 0 - 59, got " + minutes); if (seconds < 0 || seconds > 59) throw new IllegalArgumentException("Seconds must be between 0 - 59, got " + seconds); this.year = year; this.month = (byte)month; this.day = (byte)day; this.hours = (byte)hours; this.minutes = (byte)minutes; this.seconds = (byte)seconds; this.offset = offset; } @Override public int getYear() { return year; } @Override public int getMonth() { return month; } @Override public int getDate() { return day; } @Override public int getHours() { return hours; } @Override public int getMinutes() { return minutes; } @Override public int getSeconds() { return seconds; } @Override public int getTimezoneOffset() { return offset; } @Override public Date getJavaDate() { Calendar c = Calendar.getInstance(); c.set(year, month, day, hours, minutes, seconds); if (offset != Integer.MIN_VALUE) { c.setTimeZone(TimeZone.getTimeZone(TimeZone.getAvailableIDs(offset*60*1000)[0])); } return c.getTime(); } @Override public int compare(org.simantics.xml.sax.base.datatypes.adt.DateTime o) { // FIXME: take account time offset if (getYear() != o.getYear()) return getYear() - o.getYear(); if (getMonth() != o.getMonth()) return getMonth() - o.getMonth(); if (getDate() != o.getDate()) return getDate() - o.getDate(); if (getHours() != o.getHours()) return getHours() - o.getHours(); if (getMinutes() != o.getMinutes()) return getMinutes() - o.getMinutes(); if (getSeconds() != o.getSeconds()) return getSeconds() - o.getSeconds(); return 0; } public static DateTime parseDateTime(String dateString) { // FIXME: XML specification allows any number of second decimals! // FIXME: endOfDayFrag handling is missing. String[] formats = new String[]{"yyyy-MM-dd'T'HH:mm:ssXXX", "yyyy-MM-dd'T'HH:mm:ssSSSSSSSXXX","yyyy-MM-dd'T'HH:mm:ss", "yyyy-MM-dd'T'HH:mm:ssSSSSSSS"}; boolean[] timezone = new boolean[]{true, true,false,false}; for (int i = 0; i< formats.length; i++) { String format = formats[i]; try { SimpleDateFormat dateFormat = new SimpleDateFormat(format); java.util.Date n = dateFormat.parse(dateString); if (timezone[i]) { return new DateTime(n.getYear()+1900, n.getMonth()+1, n.getDate(), n.getHours(),n.getMinutes(), n.getSeconds(), n.getTimezoneOffset()); } return new DateTime(n.getYear()+1900, n.getMonth()+1, n.getDate(), n.getHours(),n.getMinutes(), n.getSeconds()); } catch (ParseException e) { } } throw new IllegalArgumentException("Time is not in proper format " + dateString); } @Override public String toString() { return year + "-" + month + "-"+day + "T"+hours+ ":" + minutes + ":"+seconds; } }