package org.openntf.formula.impl;
import static com.ibm.icu.util.Calendar.DAY_OF_MONTH;
import static com.ibm.icu.util.Calendar.HOUR_OF_DAY;
import static com.ibm.icu.util.Calendar.MILLISECOND;
import static com.ibm.icu.util.Calendar.MINUTE;
import static com.ibm.icu.util.Calendar.MONTH;
import static com.ibm.icu.util.Calendar.SECOND;
import static com.ibm.icu.util.Calendar.YEAR;
import java.io.Externalizable;
import java.io.IOException;
import java.io.ObjectInput;
import java.io.ObjectOutput;
import java.util.Date;
import java.util.Locale;
import org.openntf.formula.DateTime;
import org.openntf.formula.Formulas;
import com.ibm.icu.util.Calendar;
public class DateTimeImpl implements DateTime, Externalizable {
private Locale _locale;
private Calendar _cal;
private boolean _noDate = false;
private boolean _noTime = false;
public void writeExternal(final ObjectOutput out) throws IOException {
out.writeInt(20150211);
out.writeObject(_locale);
out.writeLong(_cal.getTimeInMillis());
out.writeBoolean(_noDate);
out.writeBoolean(_noTime);
}
public void readExternal(final ObjectInput in) throws IOException, ClassNotFoundException {
in.readInt();
_locale = (Locale) in.readObject();
_cal = Calendar.getInstance(_locale);
_cal.setTimeInMillis(in.readLong());
_noDate = in.readBoolean();
_noTime = in.readBoolean();
}
/**
* @deprecated needed for {@link Externalizable} - do not use!
*/
@Deprecated
public DateTimeImpl() {
}
DateTimeImpl(final Locale loc) {
_locale = loc;
_cal = Calendar.getInstance(loc);
}
public void adjustDay(final int n) {
if (!_noDate)
_cal.add(DAY_OF_MONTH, n);
}
public void adjustHour(final int n) {
if (!_noTime)
_cal.add(HOUR_OF_DAY, n);
}
public void adjustMinute(final int n) {
if (!_noTime)
_cal.add(MINUTE, n);
}
public void adjustMonth(final int n) {
if (!_noDate)
_cal.add(MONTH, n);
}
public void adjustSecond(final int n) {
if (!_noTime)
_cal.add(SECOND, n);
}
public void adjustYear(final int n) {
if (!_noDate)
_cal.add(YEAR, n);
}
public void convertToZone(final int zone, final boolean isDST) {
// int unused;
// TODO MSt: Timezone support (Really needed?)
}
public String getDateOnly() {
if (_noDate)
return "";
return Formulas.getFormatter(_locale).formatCalDateOnly(_cal);
}
public String getLocalTime() {
if (_noDate)
return getTimeOnly();
if (_noTime)
return getDateOnly();
return Formulas.getFormatter(_locale).formatCalDateTime(_cal);
}
public String getTimeOnly() {
if (_noTime)
return "";
return Formulas.getFormatter(_locale).formatCalTimeOnly(_cal);
}
public int getTimeZone() {
// int unused;
// TODO MSt: Timezone support
return 0;
}
public String getZoneTime() {
// int unused;
// TODO MSt: Timezone support
return null;
}
public boolean isAnyDate() {
return _noDate;
}
public boolean isAnyTime() {
return _noTime;
}
public boolean isDST() {
// int unused;
// TODO MSt: Timezone support
return false;
}
public void setAnyDate() {
_noDate = true;
}
public void setAnyTime() {
_noTime = true;
}
public void setLocalDate(final int year, final int month, final int day) {
_cal.set(YEAR, year);
_cal.set(MONTH, month - 1);
_cal.set(DAY_OF_MONTH, day);
_noDate = false;
}
public void setLocalTime(final java.util.Calendar otherCal) {
setLocalTime(otherCal.getTime());
}
public void setLocalTime(final Date date) {
_cal.setTime(date);
_noDate = false;
_noTime = false;
}
public void setLocalTime(final int hour, final int minute, final int second, final int hundredth) {
_cal.set(HOUR_OF_DAY, hour);
_cal.set(MINUTE, minute);
_cal.set(SECOND, second);
_cal.set(MILLISECOND, hundredth * 10);
_noTime = false;
}
public void setLocalTime(final String time) {
setLocalTime(time, true);
}
public void setLocalTime(final String time, final boolean parseLenient) {
boolean[] noDT = new boolean[2];
_cal = Formulas.getFormatter(_locale).parseDateToCal(time, noDT, parseLenient);
_noDate = noDT[0];
_noTime = noDT[1];
}
public void setNow() {
setLocalTime(new Date());
}
public int timeDifference(final DateTime dt) {
return (int) timeDifferenceDouble(dt);
}
public double timeDifferenceDouble(final DateTime dt) {
// What if isAnyDate or isAnyTime for one of these?
return (_cal.getTimeInMillis() - dt.toJavaCal().getTimeInMillis()) / 1000;
}
public Date toJavaDate() {
return _cal.getTime();
}
public Calendar toJavaCal() {
return _cal;
}
@Override
public String toString() {
return getLocalTime();
}
public int compare(final DateTime sdt1, final DateTime sdt2) {
boolean noDate1 = sdt1.isAnyDate();
boolean noDate2 = sdt2.isAnyDate();
if (noDate1 != noDate2)
return (noDate2 ? 1 : -1);
boolean noTime1 = sdt1.isAnyTime();
boolean noTime2 = sdt2.isAnyTime();
if (noDate1) {
if (noTime1 && noTime2)
return (0);
if (noTime1 != noTime2)
return (noTime2 ? 1 : -1);
}
Calendar cal1 = sdt1.toJavaCal();
Calendar cal2 = sdt2.toJavaCal();
int i1, i2;
if (!noDate1) {
i1 = cal1.get(YEAR);
i2 = cal2.get(YEAR);
if (i1 != i2)
return (i1 > i2 ? 1 : -1);
i1 = cal1.get(MONTH);
i2 = cal2.get(MONTH);
if (i1 != i2)
return (i1 > i2 ? 1 : -1);
i1 = cal1.get(DAY_OF_MONTH);
i2 = cal2.get(DAY_OF_MONTH);
if (i1 != i2)
return (i1 > i2 ? 1 : -1);
if (noTime1 && noTime2)
return 0;
if (noTime1 != noTime2)
return (noTime2 ? 1 : -1);
}
i1 = cal1.get(HOUR_OF_DAY);
i2 = cal2.get(HOUR_OF_DAY);
if (i1 != i2)
return (i1 > i2 ? 1 : -1);
i1 = cal1.get(MINUTE);
i2 = cal2.get(MINUTE);
if (i1 != i2)
return (i1 > i2 ? 1 : -1);
i1 = cal1.get(SECOND);
i2 = cal2.get(SECOND);
if (i1 != i2)
return (i1 > i2 ? 1 : -1);
return 0;
}
@Override
public boolean equals(final Object o) {
if (o instanceof DateTime)
return (compare(this, (DateTime) o) == 0);
return super.equals(o);
}
}