/*
Copyright (c) 2003-2008 ITerative Consulting Pty Ltd. All Rights Reserved.
Redistribution and use in source and binary forms, with or without modification, are permitted
provided that the following conditions are met:
o Redistributions of source code must retain the above copyright notice, this list of conditions and
the following disclaimer.
o Redistributions in binary form must reproduce the above copyright notice, this list of conditions
and the following disclaimer in the documentation and/or other materials provided with the distribution.
o This jcTOOL Helper Class software, whether in binary or source form may not be used within,
or to derive, any other product without the specific prior written permission of the copyright holder
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING,
BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
package Framework;
import java.beans.PropertyChangeEvent;
import java.io.Serializable;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.GregorianCalendar;
import java.util.Locale;
import java.util.TimeZone;
/**
* Class for managing date/time calendar values.
* <P>
* An implementation that wraps Java's {@link java.util.Date} class.
* <P>
*/
public class DateTimeData extends DataValue implements Comparable<DataValue>, Serializable, Cloneable {
/**
* Resolves ambiguous constructor arguments
*/
public static class qq_Resolver {
public static final int cISNULL = 1;
public static final int cVALUE = 2;
public static final int cTEXTVALUE = 3;
public static final int cISNULL_TEXTVALUE = 4;
public static final int cISNULL_VALUE = 5;
}
/**
* theValue is where this object stores its value
*/
//protected GregorianCalendar theValue;
protected Date theDate;
private static final int millisPerHour = 60 * 60 * 1000;
// private static final int millisPerMin = 60 * 1000;
private int hoursFromGMT = 0;
private int minutesFromGMT = 0;
private boolean isDST = false;
public static final String ORACLE_FORTE_DATE_FORMAT = "dd-Mon-yyyy HH24:mi:ss";
// TF:11/10/07:The correct gregorian start is 12:00 (noon) on 15th Oct, 1582. Some people
// rely on this time exactly, so we need to get this correct.
//public static final long GREGORIAN_START_AS_LONG = -12219292800000L;
public static final long GREGORIAN_START_AS_LONG = -12219249600000L;
// TF:30/03/2009:created a cached GregorianCalendar rather than re-creating them
@CloneReferenceOnly(nullReference=true)
private transient GregorianCalendar cachedCalendar = null;
/**
* Default constructor
*/
public DateTimeData() {
super();
// theValue = new GregorianCalendar(); // gives current time
// Date gregorianStart = theValue.getGregorianChange();
// theValue.setTime(gregorianStart);
this.theDate = new Date(DateTimeData.GREGORIAN_START_AS_LONG);
this.setCreationValues(this.theDate);
}
public DateTimeData(GregorianCalendar value) {
super();
this.theDate = value.getTime();
this.setCreationValues(this.theDate);
}
public DateTimeData(Date value) {
super();
// theValue = new GregorianCalendar();
// theValue.setTime(value);
// this.setCreationValues(this.theValue);
this.theDate = value;
this.setCreationValues(this.theDate);
}
public DateTimeData(DateTimeData value) {
super();
this.setValue( value.dateValue() );
this.setCreationValues(this.theDate);
}
public DateTimeData(int year, int month, int day, int hour, int minute,
int second) {
super();
GregorianCalendar theValue = new GregorianCalendar((short) year, (short) month - 1,
(short) day, (short) hour, (short) minute, (short) second);
this.theDate = theValue.getTime();
theValue = null;
this.setCreationValues(this.theDate);
}
public DateTimeData(TextData pValue, int pResolver) {
super();
if (pResolver == DateTimeData.qq_Resolver.cVALUE)
this.setValue(pValue);
else if (pResolver == DateTimeData.qq_Resolver.cTEXTVALUE)
this.setValue(pValue);
this.setCreationValues(this.theDate);
}
public DateTimeData(String pValue, String format) {
super();
this.setValue(pValue, format);
this.setCreationValues(this.theDate);
}
public DateTimeData(Object pValue, String format) {
super();
this.setValue(pValue, format);
this.setCreationValues(this.theDate);
}
public DateTimeData(String pValue, int pResolver) {
super();
if (pResolver == DateTimeData.qq_Resolver.cVALUE)
this.setValue(pValue);
else if (pResolver == DateTimeData.qq_Resolver.cTEXTVALUE)
this.setValue(pValue);
this.setCreationValues(this.theDate);
}
public DateTimeData(boolean pValue, int pResolver) {
super();
if (pResolver == DateTimeData.qq_Resolver.cISNULL) {
//this.theValue = new GregorianCalendar(1582,9,15,10,0);
this.theDate = new Date(DateTimeData.GREGORIAN_START_AS_LONG);
}
this.setCreationValues(this.theDate);
}
public DateTimeData(boolean pBool, TextData pValue, int pResolver) {
super();
if (pResolver == DateTimeData.qq_Resolver.cISNULL_VALUE) {
this.setValue(pValue);
// this.isNull = pBool1;
} else if (pResolver == DateTimeData.qq_Resolver.cISNULL_TEXTVALUE) {
this.setValue(pValue);
// this.isNull = pBool1;
}
this.setCreationValues(this.theDate);
}
public DateTimeData(boolean pBool, String pValue, int pResolver) {
super();
if (pResolver == DateTimeData.qq_Resolver.cISNULL_VALUE) {
this.setValue(pValue);
// this.isNull = pBool1;
} else if (pResolver == DateTimeData.qq_Resolver.cISNULL_TEXTVALUE) {
this.setValue(pValue);
// this.isNull = pBool1;
}
this.setCreationValues(this.theDate);
}
public DateTimeData(String pValue)
{
super();
this.setValue(pValue);
this.setCreationValues(this.theDate);
}
/**
* Get a gregorian calendar. The state of the returned calendar is unknown
* and should always be appropriately initialised.
*/
private GregorianCalendar getGregorianCalendar() {
if (this.cachedCalendar == null) {
this.cachedCalendar = new GregorianCalendar();
}
return this.cachedCalendar;
}
/**
* Add - this variation of the Add method adds a specified IntervalData
* value to a specified DateTimeData value and replaces the original
* DateTimeData value with the result.
* <P>
* <P>
* Add - this variation of the Add method adds a specified IntervalData
* value to a specified DateTimeData value and replaces the original
* DateTimeData value with the result.
*
* @return the DateTimeData object.
* @param source2
* IntervalData to add to DateTimeData
* @param source1
* DateTimeData to which IntervalData is added
*/
public DateTimeData add(DateTimeData source1, IntervalData source2) {
if (source1 == null || source2 == null)
data_RaiseNilOperandExcpt();
if (source1.checkNullValue() || source2.checkNullValue()) {
setNull();
return (this);
}
// TF:30/03/2009:Changed this from new GregorianCalendar() to use the cached value
GregorianCalendar newValue = getGregorianCalendar();
newValue.setTime(source1.dateValue());
newValue.add(Calendar.YEAR, source2.year);
newValue.add(Calendar.MONTH, source2.month);
newValue.add(Calendar.DAY_OF_MONTH, source2.day);
newValue.add(Calendar.HOUR_OF_DAY, source2.hour);
newValue.add(Calendar.MINUTE, source2.min);
newValue.add(Calendar.SECOND, source2.sec);
newValue.add(Calendar.MILLISECOND, (int)source2.msec);
setValue(newValue);
super.reportChange();
return this;
}
/**
* Add - this variation of the Add method adds a specified IntervalData
* value to the original DateTimeData value and replaces this DateTimeData.
* <P>
* <P>
* Add - this variation of the Add method adds a specified IntervalData
* value to the original DateTimeData value and replaces this DateTimeData.
*
* @return the DateTimeData object.
* @param source
* IntervalData to add to DateTimeData
*/
public DateTimeData add(IntervalData source) {
if (source == null)
data_RaiseNilOperandExcpt();
return (add(this, source));
}
/**
* AdjustZoneAndTime changes the creation time zone and adjusts the
* internally stored time by the difference between the new and the original
* time zones.
* <P>
* <P>
* IMPLEMENTATION Use setRawOffset; no adjustment to base time necessary.
*
* @param minutesFromGMT
* number of minutes from GMT
* @param hoursFromGMT
* number of hours from GMT
*/
public void adjustZoneAndTime(int hoursFromGMT, int minutesFromGMT) {
//TimeZone tz = theValue.getTimeZone();
//tz.setRawOffset((hoursFromGMT * millisPerHour)
// + (minutesFromGMT * millisPerMin));
this.hoursFromGMT = hoursFromGMT;
this.minutesFromGMT = minutesFromGMT;
super.reportChange();
}
/**
* AdjustZoneAndTime changes the creation time zone and adjusts the
* internally stored time by the difference between the new and the original
* time zones.
* <P>
* <P>
* IMPLEMENTATION Use setRawOffset; no adjustment to base time necessary.
*
* @param minutesFromGMT
* number of minutes from GMT
*/
public void adjustZoneAndTime(int hoursFromGMT) {
this.hoursFromGMT = hoursFromGMT;
super.reportChange();
}
/**
* DayOfWeek
* <P>
* <P>
* description of method
*
* @return int
*/
public int dayOfWeek() {
// TF:30/03/2009:Changed this from new GregorianCalendar() to use the cached value
GregorianCalendar cal = getGregorianCalendar();
cal.setTime(this.theDate);
return cal.get(Calendar.DAY_OF_WEEK);
}
/**
* DecodeValue
* <P>
* <P>
* description of method
*
* @param format
* format with which to decode text
* @param source
* text to be decoded
*/
public void decodeValue(TextData source, DateFormat format ) {
this.setValue(format.decodeDate(source));
}
/**
* DecodeValue
* <P>
* <P>
* description of method
*
* @param format
* format with which to decode text
* @param source
* text to be decoded
*/
public void decodeValue(String source, DateFormat format ) {
this.setValue(format.decodeDate(source));
}
/**
* FillString
* <P>
* <P>
* description of method
*
* @param target
* string to be filled in
*/
public void fillString(TextData target) {
if (target != null)
target.setValue(this.toString());
}
/**
* getHoursFromGmt
* <P>
* <P>
* returns value of int attribute
*
* @return value of int attribute
*/
public int getHoursFromGmt() {
/* int hourHere = this.theValue.get(Calendar.HOUR_OF_DAY);
// Make a new calendar object based on GMT and
// not chaning the calendar that is part of this
//object
Calendar gmtCal = new GregorianCalendar(TimeZone.getTimeZone("GMT"));
int gmtHour = gmtCal.get(Calendar.HOUR_OF_DAY);
return gmtHour - hourHere;*/
return this.hoursFromGMT;
}
/**
* getDST
* <P>
* <P>
* returns value of boolean attribute
*
* @return value of boolean attribute
*/
public boolean getDST() {
//boolean isDST = false;
//int dstOffset = this.theValue.get(Calendar.DST_OFFSET);
//Logger.getLogger("task.part.logmgr").debug("DST offset is: " + dstOffset);
//if (dstOffset == 0) {
// isDST = true;
//}
//return isDST;
return this.isDST;
}
/**
* getMinutesFromGmt
* <P>
* <P>
* returns value of int attribute
*
* @return value of int attribute
*/
public int getMinutesFromGmt() {
/* int minuteHere = this.theValue.get(Calendar.MINUTE);
// Make a new calendar object based on GMT and
// not chaning the calendar that is part of this
//object
Calendar gmtCal = new GregorianCalendar(TimeZone.getTimeZone("GMT"));
int gmtMinute = gmtCal.get(Calendar.MINUTE);
return gmtMinute - minuteHere;*/
return this.minutesFromGMT;
}
/**
* getUnit
* <P>
* <P>
* description of method
*
* @return int
* @param resolution
* the part of the date to fetch
*/
public int getUnit(int resolution) {
return this.getUnit(resolution, Constants.TZ_CREATION_ZONE);
}
/**
* getUnit
* <P>
* <P>
* description of method
*
* @return int
* @param resolution
* the part of the date to fetch
* @param timezone
* the timezone to use
*/
public int getUnit(int resolution, int timezone) {
int theUnit = 0;
// TF:30/03/2009:Changed this from new GregorianCalendar() to use the cached value
GregorianCalendar theValue = getGregorianCalendar();
theValue.setTime(this.theDate);
TimeZone creationTimeZone = theValue.getTimeZone();
if (timezone == Constants.TZ_GMT) {
theValue.setTimeZone(TimeZone.getTimeZone("GMT")); //$NON-NLS-1$
} else if (timezone == Constants.TZ_LOCAL) {
theValue.setTimeZone(TimeZone.getDefault());
}
switch (resolution) {
case Constants.DR_YEAR: {
theUnit = theValue.get(Calendar.YEAR);
break;
}
case Constants.DR_QUARTER: {
int month = theValue.get(Calendar.MONTH);
switch (month) {
case 0:
case 1:
case 2: {
theUnit = 1;
break;
}
case 3:
case 4:
case 5: {
theUnit = 2;
break;
}
case 6:
case 7:
case 8: {
theUnit = 3;
break;
}
case 9:
case 10:
case 11: {
theUnit = 4;
break;
}
}
break;
}
case Constants.DR_MONTH: {
// ISSUE 35 - Java returns January as 0 - need to increment by 1
theUnit = theValue.get(Calendar.MONTH) + 1;
break;
}
case Constants.DR_DAY: {
theUnit = theValue.get(Calendar.DAY_OF_MONTH);
break;
}
case Constants.DR_HOUR: {
theUnit = theValue.get(Calendar.HOUR);
// ISSUE 35 - Added check for AM/PM to ensure 24 hour value returned
if (theValue.get(Calendar.AM_PM) == Calendar.PM)
theUnit = theUnit + 12;
break;
}
case Constants.DR_MINUTE: {
theUnit = theValue.get(Calendar.MINUTE);
break;
}
case Constants.DR_SECOND: {
theUnit = theValue.get(Calendar.SECOND);
break;
}
}
theValue.setTimeZone(creationTimeZone);
return theUnit;
}
/**
* isEqual Comparison operator that returns nullable boolean object.
* <P>
* <P>
* Compares the object with the source and return true if the two are equal,
* false otherwise However, if the source is null, the result is null.
*
* @return BooleanNullable true if source object is equal to this
* @param source
* object to compare
*/
public BooleanNullable isEqual(DateTimeData source) {
BooleanNullable isEqual = new BooleanNullable(false);
if (this.theDate.getTime() == source.dateValue().getTime()) {
isEqual.setValue(true);
}
return isEqual;
}
/**
* isGreaterThan comparison operator that returns nullable boolean object.
* <P>
* <P>
* Compares the object with the source and return true if the object is
* greater than the source, false otherwise However, if the source is null,
* the result is null.
*
* @return true if this object has a greater value than the source object
* @param source
* other object to compare with this object
*/
public BooleanNullable isGreaterThan(DateTimeData source) {
BooleanNullable isGreaterThan = new BooleanNullable(false);
if (this.theDate.getTime() > source.dateValue().getTime()) {
isGreaterThan.setValue(true);
}
return isGreaterThan;
}
/**
* isLessThan comparison operator returns nullable boolean object.
* <P>
* <P>
* Compares the object with the source and return true if the object is less
* than the source, false otherwise However, if the source is null, the
* result is null.
*
* @return true if this object has a lesser value than source
* @param source
* other object to compare with this object
*/
public BooleanNullable isLessThan(DateTimeData source) {
BooleanNullable isLessThan = new BooleanNullable(false);
if (this.theDate.getTime() < source.dateValue().getTime()) {
isLessThan.setValue(true);
}
return isLessThan;
}
/**
* isNotEqual comparison operator that returns nullable boolean object.
* <P>
* <P>
* Compares the object with the source and return true if the two are not
* equal, false otherwise However, if the source is null, the result is
* null.
*
* @return true if the source object is not equal to this object
* @param source
* to be compared with object
*/
public BooleanNullable isNotEqual(DateTimeData source) {
BooleanNullable isNotEqual = new BooleanNullable(false);
if (this.theDate.getTime() != source.dateValue().getTime()) {
isNotEqual.setValue(true);
}
return isNotEqual;
}
/**
* setCurrent replcaes the value of this object with the current time
* <P>
* <P>
* description of method
*
* @return DateTimeData the new object
* @param resolution
* part of time to set
*/
public DateTimeData setCurrent(int resolution) {
this.hasNullValue = false; //PM:9/10/07 set null flag
// TF:30/03/2009:Changed this from new GregorianCalendar() to use the cached value
GregorianCalendar theValue = getGregorianCalendar();
theValue.setTime(new Date());
switch (resolution) {
case Constants.DR_YEAR: {
// TF:19/12/2009:DET-145:Made sure the year was set correctly
int year = theValue.get(Calendar.YEAR);
theValue.clear();
theValue.set(year, Calendar.JANUARY, 1);
break;
}
case Constants.DR_QUARTER: {
throw new RuntimeException(
"DateTimeData.setCurrent(DR_QUATER) is not implemented"); //$NON-NLS-1$
}
case Constants.DR_MONTH: {
// TF:19/12/2009:DET-145:Set the day of the month properly
theValue.set(Calendar.DAY_OF_MONTH, 1);
theValue.set(Calendar.HOUR_OF_DAY, 0);
theValue.set(Calendar.MINUTE, 0);
theValue.set(Calendar.SECOND, 0);
break;
}
case Constants.DR_DAY: {
theValue.set(Calendar.HOUR_OF_DAY, 0);
theValue.set(Calendar.MINUTE, 0);
theValue.set(Calendar.SECOND, 0);
break;
}
case Constants.DR_HOUR: {
theValue.set(Calendar.MINUTE, 0);
theValue.set(Calendar.SECOND, 0);
break;
}
case Constants.DR_MINUTE: {
theValue.set(Calendar.SECOND, 0);
break;
}
case Constants.DR_SECOND: {
break;
}
}
// Forte only sets current to the millisecond, so we can too
theValue.set(Calendar.MILLISECOND, 0);
super.reportChange();
this.theDate = theValue.getTime();
this.setCreationValues(this.theDate);
return this;
}
public DateTimeData setCurrent() {
this.theDate = new Date();
// Forte only sets current to the millisecond, so we can too
//this.theValue.set(Calendar.MILLISECOND, 0);
super.reportChange();
return this;
}
public Date dateValue() {
return this.theDate;
}
/**
* setHoursFromGmt
* <P>
* <P>
* sets value of int attribute
*
* @param value -
* set int attribute
*/
public void setHoursFromGmt(int value) {
this.hoursFromGMT = value;
super.reportChange();
}
public void setIsNull(boolean value) {
if (value) {
//this.theDate = new Date();
//
// According to the UDS documentation, an attempt to set isNull to true
// on a non-nullable class should result in a DataTypeException.
//
DatatypeException errorVar = new DatatypeException();
ErrorMgr.addError(errorVar);
throw errorVar;
}
//super.setIsNull(value);
}
public void setNull() {
//
// According to the UDS documentation, an attempt to set isNull to true
// on a non-nullable class should result in a DataTypeException.
//
DatatypeException errorVar = new DatatypeException();
ErrorMgr.addError(errorVar);
throw errorVar;
};
/**
* setMinutesFromGmt
* <P>
* <P>
* sets value of int attribute
*
* @param value -
* set int attribute
*/
public void setMinutesFromGmt(int value) {
this.minutesFromGMT = value;
super.reportChange();
}
/**
* setDST
* <P>
* <P>
* sets value of boolean attribute
*
* @param value -
* set boolean attribute
*/
public void setDST(boolean value) {
this.isDST = value;
super.reportChange();
}
/**
* setValue
* <P>
* <P>
* description of method
*
* @param source
* value to set object to
*/
public void setValue(GregorianCalendar source) {
if (source == null) {
data_RaiseNilOperandExcpt();
} else {
theDate = source.getTime();
clearNull();
reportChange();
}
}
/**
* setValue
* <P>
* <P>
* description of method
*
* @param source
* value to set object to
*/
public void setValue(Date source) {
if (source == null) {
data_RaiseNilOperandExcpt();
} else {
// theValue = new GregorianCalendar();
// theValue.setTime(source);
this.theDate = source;
this.setCreationValues(this.theDate);
clearNull();
reportChange();
}
}
public void setValue(Object source, String format) {
setValue(source.toString(), format);
}
public void setValue(String source, String format) {
SimpleDateFormat sdf = new SimpleDateFormat(format);
try {
setValue(sdf.parse(source));
} catch (ParseException e) {
UsageException errorVar = new UsageException("Date format error", e);
ErrorMgr.addError(errorVar);
throw errorVar;
}
}
/**
* Set the value of this datetimedata to the passed value
*/
public void setValue(String pValue) {
// TF:10/07/2008:Changed this to invoke the TextData overload because that's the way
// forte worked, and some people rely on this overload being called, particularly for
// domain classes.
this.setValue(new TextData(pValue));
}
/**
* Set the value of this datetimedata to the passed value
*/
public void setValue(TextData pValue) {
// TF:10/07/2008:Made this the main method to set the value rather than the string
// overload as this makes some domain classes work
this._setValue(pValue.toString());
}
//PM:23/7/2008:Improved multil lingual support
private static class FormatLocale{
public String format;
public Locale locale;
public FormatLocale(String format, String language, String country){
this.format = format;
this.locale = new Locale(language, country);
}
public FormatLocale(String format){
this.format = format;
this.locale = Locale.getDefault();
}
}
//PM:23/7/2008:Improved multilingual support
private static FormatLocale[] formats = {
// TF:29/12/2009:DET-147:Corrected this pattern
new FormatLocale("yyyy-MM-dd HH:mm:ss.S"), // AD:12/8/2008 Added for Kintetsu
new FormatLocale("dd MMMMM yyyy HH:mm", "en", "US"),
new FormatLocale("dd-MMM-yyyy HH:mm:ss", "en", "US"),
new FormatLocale("dd-MMMM-yyyy HH:mm:ss", "en", "US"),
new FormatLocale("dd-MMM-yyyy HH:mm", "en", "US"),
new FormatLocale("dd-MMMM-yyyy HH:mm", "en", "US"),
new FormatLocale("dd-MMM-yyyy", "en", "US"),
new FormatLocale("HH:mm", "en", "US"),
new FormatLocale("dd MMMMM yyyy HH:mm"),
new FormatLocale("dd-MMM-yyyy HH:mm:ss"),
new FormatLocale("dd-MMMM-yyyy HH:mm:ss"),
new FormatLocale("dd-MMM-yyyy HH:mm"),
new FormatLocale("dd-MMMM-yyyy HH:mm"),
new FormatLocale("dd-MMM-yyyy"),
new FormatLocale("HH:mm")
};
private void _setValue(String source) {
if (source == null) {
data_RaiseNilOperandExcpt();
} else {
Date date = new Date();
try {
if (source.length() > 0 && !source.equals(DataValue.NL_FMSG_NULLVALUE)){
date = java.text.DateFormat.getDateTimeInstance().parse(source);
clearNull();
theDate = date; //Allshare
}
else {
theDate = date;
setIsNull(true);
}
} catch (ParseException e) {
ParseException except = null; //PM:23/7/2008:Improved multil lingual support
for (FormatLocale fl : formats){
try {
SimpleDateFormat sdf = new SimpleDateFormat(fl.format, fl.locale);
theDate = sdf.parse(source);
clearNull();
reportChange();
except = null;
break;
} catch (ParseException ex) {
except = ex;
}
}
if (except != null){
// TF:11/10/07: Changed this to throw a usage exception as this is what Forte does
// Logger.getLogger("task.part.logmgr").error("DateTimeData.setValue(), parse error", aParseException3); //$NON-NLS-1$ //$NON-NLS-2$
UsageException errorVar = new UsageException(except);
ErrorMgr.addError(errorVar);
throw errorVar;
}
}
}
reportChange();
}
/**
* setValue
* <P>
* <P>
* description of method
*
* @param source
* value to set object to
*/
/*
* public void setValue(DataValue source) { }
*/
/**
* setValue
* <P>
* <P>
* description of method
*
* @param source
* value to set object to
*/
/*
* public void setValue(TextData source) { }
*/
/**
* setValue
* <P>
* <P>
* description of method
*
* @param source
* value to set object to
*/
/*
* public void setValue(String source) { }
*/
/**
* setValue
* <P>
* <P>
* description of method
*
* @param source
* value to set object to
*/
public void setValue(DateTimeData source) {
// TF:Aug 21, 2008:Fixed up this method
if (source == null) {
data_RaiseInvalidMethodExcpt();
} else if (source.hasNullValue) {
setIsNull(true);
} else {
setValue(source.dateValue());
}
}
/**
* Subtract set value to the difference between the two arguments
* <P>
* <P>
* set the value of the object to the difference between source1 and source2
* (source1 - source2)
*
* @param source2
* second argument
* @param source1
* first argument
*/
public DateTimeData subtract(DateTimeData source1, IntervalData source2) {
if (source1 == null || source2 == null)
data_RaiseNilOperandExcpt();
if (source1.checkNullValue() || source2.checkNullValue()) {
setNull();
super.reportChange();
return (this);
}
// TF:30/03/2009:Changed this from new GregorianCalendar() to use the cached value
GregorianCalendar newValue = getGregorianCalendar();
newValue.setTime(source1.dateValue());
newValue.add(Calendar.YEAR, -source2.year);
newValue.add(Calendar.MONTH, -source2.month);
newValue.add(Calendar.DAY_OF_MONTH, -source2.day);
newValue.add(Calendar.HOUR_OF_DAY, -source2.hour);
newValue.add(Calendar.MINUTE, -source2.min);
newValue.add(Calendar.SECOND, -source2.sec);
newValue.add(Calendar.MILLISECOND, (int)-source2.msec);
setValue(newValue);
return this;
}
/**
* Subtract set value to the DateTimeData argument minus the Interval
* <P>
* <P>
* set the value of the object to the difference between DateTimeData and
* source
*
* @return DateTimeData
* @param source
* the interval
*/
//
public DateTimeData subtract(IntervalData source) {
if (source == null)
data_RaiseNilOperandExcpt();
return (subtract(this, source));
}
/**
* toGregorianCalendar - returns the underlying GregorianCalendar
* <P>
* <P>
* returns the underlying GregorianCalendar IMPLEMENTATION Must be used with
* caution. If the underlying GregorianCalendar is changed the DateTimeData
* object may become inconsistent.
*
* @return the underlying GregorianCalendar
*/
public GregorianCalendar toGregorianCalendar() {
if (checkNullValue())
data_RaiseInvalidMethodExcpt();
GregorianCalendar cal = new GregorianCalendar();
cal.setTime(this.theDate);
return cal;
}
public boolean equals(Object obj) {
if (this == obj)
return (true);
if (obj == null)
return (false);
if (!(obj instanceof DateTimeData))
return (false);
// TF:30/03/2009:Changed this from new GregorianCalendar() to use the cached value
GregorianCalendar theValue = getGregorianCalendar();
theValue.setTime(this.theDate);
short year = (short) theValue.get(Calendar.YEAR);
short month = (short) (theValue.get(Calendar.MONTH) + 1);
short day = (short) theValue.get(Calendar.DAY_OF_MONTH);
short hour = (short) theValue.get(Calendar.HOUR_OF_DAY);
short min = (short) theValue.get(Calendar.MINUTE);
short sec = (short) theValue.get(Calendar.SECOND);
short msec = (short) theValue.get(Calendar.MILLISECOND);
TimeZone tz = (TimeZone) theValue.getTimeZone();
int rawOffset = tz.getRawOffset();
String id = tz.getID();
// TF:30/03/2009:Changed this from new GregorianCalendar() to use the cached value
GregorianCalendar value2 = ((DateTimeData)obj).getGregorianCalendar();
value2.setTime(((DateTimeData) obj).dateValue());
short year2 = (short) value2.get(Calendar.YEAR);
short month2 = (short) (value2.get(Calendar.MONTH) + 1);
short day2 = (short) value2.get(Calendar.DAY_OF_MONTH);
short hour2 = (short) value2.get(Calendar.HOUR_OF_DAY);
short min2 = (short) value2.get(Calendar.MINUTE);
short sec2 = (short) value2.get(Calendar.SECOND);
short msec2 = (short) value2.get(Calendar.MILLISECOND);
TimeZone tz2 = (TimeZone) value2.getTimeZone();
int rawOffset2 = tz2.getRawOffset();
String id2 = tz2.getID();
if (year != year2)
return (false);
if (month != month2)
return (false);
if (day != day2)
return (false);
if (hour != hour2)
return (false);
if (min != min2)
return (false);
if (sec != sec2)
return (false);
if (msec != msec2)
return (false);
if (rawOffset != rawOffset2)
return (false);
if (!id.equals(id2))
return (false);
return (true);
}
public String toString() {
if (this.theDate == null || this.getIsNull())
return DataValue.NL_FMSG_NULLVALUE;
SimpleDateFormat sdf = new SimpleDateFormat("dd-MMM-yyyy HH:mm:ss", Locale.getDefault());
String fsz;
fsz = sdf.format(this.theDate);
return (fsz);
}
public TextData getTextValue() {
if (theDate == null)
return new TextData(DataValue.NL_FMSG_NULLVALUE);
return (new TextData(this.toString()));
}
public void setTextValue(TextData value){
setValue(value);
}
public void setTextValue(String value){
setValue(value);
}
public TextData getValue() {
return this.getTextValue();
}
public String getFormattedDate(String pFormat) {
String lvReturn = null;
SimpleDateFormat sdf = new SimpleDateFormat(pFormat);
lvReturn = sdf.format(theDate);
return lvReturn;
}
public int compareValue(DataValue pSource, boolean pConvert, boolean pIgnoreCase) {
int result = Constants.DV_CMP_NIL;
if (pSource == null) {
return Constants.DV_CMP_NIL;
}
DateTimeData convertedDTD = null;
try {
convertedDTD = (DateTimeData)(pSource);
} catch (ClassCastException cce) {
return Constants.DV_CMP_UNCONVERTIBLE;
}
BooleanNullable bn = this.isEqual(convertedDTD);
if (bn.getValue()) {
return Constants.DV_CMP_EQ;
}
bn = this.isGreaterThan(convertedDTD);
if (bn.getValue()) {
return Constants.DV_CMP_GT;
}
bn = this.isLessThan(convertedDTD);
if (bn.getValue()) {
return Constants.DV_CMP_LT;
}
return result;
}
public int compareValue(DataValue pSource, boolean pConvert) {
return compareValue(pSource,pConvert,false);
}
public int compare(DataValue pSource){
return compareValue(pSource);
}
public int compareValue(DataValue pSource) {
return compareValue(pSource,true,false);
}
/* (non-Javadoc)
* @see java.lang.Comparable#compareTo(java.lang.Object)
*/
public int compareTo(DataValue pObj) {
// TF:9/4/08:Made this method use generics
// if (pObj instanceof DataValue) {
return this.compare(pObj);
// }
// return this.toString().compareTo(pObj.toString());
}
public DateTimeData getCopyData() {
DateTimeData lvReturn = new DateTimeData(this);
return lvReturn;
}
//TF:Mar 19, 2010: use CloneHelper instead
// public Object clone() {
// return this.clone(false);
// }
//
// public Object clone(boolean pDeep) {
// DateTimeData result = new DateTimeData();
// this.duplicateIntoTarget(result, pDeep);
// return result;
// }
public void duplicateIntoTarget(DateTimeData pData, boolean pDeep) {
super.duplicateIntoTarget(pData,pDeep);
if (pDeep) {
pData.theDate = (this.theDate == null) ? null : (Date)this.theDate.clone();
}
else {
pData.theDate = this.theDate;
}
}
// protected void setCreationValues(GregorianCalendar cal) {
// TimeZone tz = theValue.getTimeZone();
// int rawOffset = tz.getRawOffset();
// this.hoursFromGMT = (rawOffset / DateTimeData.millisPerHour) * -1;
// this.isDST = tz.inDaylightTime(this.theValue.getTime());
// }
protected void setCreationValues(Date pDate) {
//TimeZone tz = theValue.getTimeZone();
TimeZone tz = TimeZone.getDefault();
int rawOffset = tz.getRawOffset();
this.hoursFromGMT = (rawOffset / DateTimeData.millisPerHour) * -1;
this.isDST = tz.inDaylightTime(pDate);
}
public void propertyChange(PropertyChangeEvent arg0) {
// -----------------------------------------------------------------------
// TF:29/01/2010:JCT-640:Changed this to invoke a method on the superclass
// -----------------------------------------------------------------------
this.firePropertyChange("VALUE", null, this.theDate); //$NON-NLS-1$
}
/**
* returns the value of the DateTimeData as a Java Date
* @return
*/
public Date asDate(){
return this.theDate;
}
/**
* An internal forte method to easily find the type of a DataValue subclass
*/
public int dataType() {
return Constants.DV_DT_DATETIME;
}
public void decodeValue(TextData text, DataFormat format) {
if (format instanceof DateFormat)
this.decodeValue(text, format);
}
/**
* The IsDST attribute (boolean) indicates that the date was set while daylight savings time was in effect.
* The runtime system sets the IsDST attribute whenever the SetCurrent method is invoked, using the value of the daylight savings setting of the current computer.
* You can also set the attribute explicitly
* @return
*/
public boolean isDST() {
return this.isDST;
}
public DateTimeData add(IntervalData source, boolean ignoreDST) {
if (source == null)
data_RaiseNilOperandExcpt();
return (add(this, source,ignoreDST));
}
//CONV_REM:jm added to support TimeZone Stuff
public DateTimeData add(DateTimeData source1, IntervalData source2,boolean ignoreDST) {
if (source1 == null || source2 == null)
data_RaiseNilOperandExcpt();
if (source1.checkNullValue() || source2.checkNullValue()) {
setNull();
return (this);
}
// TF:30/03/2009:Changed this from new GregorianCalendar() to use the cached value
GregorianCalendar newValue = getGregorianCalendar();
newValue.setTime(source1.dateValue());
TimeZone tz = newValue.getTimeZone();
newValue.add(Calendar.YEAR, source2.year);
newValue.add(Calendar.MONTH, source2.month);
newValue.add(Calendar.DAY_OF_MONTH, source2.day);
newValue.add(Calendar.HOUR_OF_DAY, source2.hour);
newValue.add(Calendar.MINUTE, source2.min);
newValue.add(Calendar.SECOND, source2.sec);
newValue.add(Calendar.MILLISECOND, (int)source2.msec);
if(tz.inDaylightTime(newValue.getTime())){
newValue.add(Calendar.HOUR_OF_DAY, -1);
}
setValue(newValue);
super.reportChange();
return this;
}
@Override
// AD:Aug 15, 2008 - Override DataValue for more efficient setting if of the same type
public void setValue(DataValue source) {
if (source instanceof DateTimeData) {
setValue((DateTimeData) source);
} else {
super.setValue(source);
}
}
//PM:6 Nov 2008:override DataValue to provide the correct value
@Override
public String asString() {
return toString();
}
}