added DATE14
This commit is contained in:
@@ -41,6 +41,8 @@ public enum IsoType {
|
||||
LLVAR(false, 0),
|
||||
/** A variable length alphanumeric value with a 3-digit header length. */
|
||||
LLLVAR(false, 0),
|
||||
/** A date in format YYYYMMddHHmmss */
|
||||
DATE14(false, 14),
|
||||
/** A date in format MMddHHmmss */
|
||||
DATE10(false, 10),
|
||||
/** A date in format MMdd */
|
||||
@@ -82,7 +84,7 @@ public enum IsoType {
|
||||
return length;
|
||||
}
|
||||
|
||||
/** Formats a Date if the receiver is DATE10, DATE4, DATE_EXP, DATE12 or TIME; throws an exception
|
||||
/** Formats a Date if the receiver is DATE10, DATE4, DATE_EXP, DATE12, DATE14 or TIME; throws an exception
|
||||
* otherwise. */
|
||||
public String format(final Date value, final TimeZone tz) {
|
||||
final SimpleDateFormat sdf;
|
||||
@@ -96,6 +98,8 @@ public enum IsoType {
|
||||
sdf = new SimpleDateFormat("HHmmss");
|
||||
} else if (this == DATE12) {
|
||||
sdf = new SimpleDateFormat("yyMMddHHmmss");
|
||||
} else if (this == DATE14) {
|
||||
sdf = new SimpleDateFormat("YYYYMMddHHmmss");
|
||||
} else {
|
||||
throw new IllegalArgumentException("Cannot format date as " + this);
|
||||
}
|
||||
|
||||
@@ -334,7 +334,8 @@ public class IsoValue<T> implements Cloneable {
|
||||
} else if (type == IsoType.AMOUNT) {
|
||||
buf = new byte[6];
|
||||
} else if (type == IsoType.DATE10 || type == IsoType.DATE4 ||
|
||||
type == IsoType.DATE_EXP || type == IsoType.TIME || type == IsoType.DATE12) {
|
||||
type == IsoType.DATE_EXP || type == IsoType.TIME ||
|
||||
type == IsoType.DATE12 || type == IsoType.DATE14) {
|
||||
buf = new byte[length / 2];
|
||||
}
|
||||
//Encode in BCD if it's one of these types
|
||||
|
||||
@@ -446,7 +446,9 @@ public class MessageFactory<T extends IsoMessage> {
|
||||
m.setField(i, val);
|
||||
if (val != null) {
|
||||
if (val.getType() == IsoType.NUMERIC || val.getType() == IsoType.DATE10
|
||||
|| val.getType() == IsoType.DATE4 || val.getType() == IsoType.DATE12
|
||||
|| val.getType() == IsoType.DATE4
|
||||
|| val.getType() == IsoType.DATE12
|
||||
|| val.getType() == IsoType.DATE14
|
||||
|| val.getType() == IsoType.DATE_EXP
|
||||
|| val.getType() == IsoType.AMOUNT
|
||||
|| val.getType() == IsoType.TIME) {
|
||||
|
||||
@@ -87,7 +87,7 @@ public class CompositeField implements CustomBinaryField<CompositeField> {
|
||||
if (v.getType() == IsoType.NUMERIC || v.getType() == IsoType.DATE10
|
||||
|| v.getType() == IsoType.DATE4 || v.getType() == IsoType.DATE_EXP
|
||||
|| v.getType() == IsoType.AMOUNT || v.getType() == IsoType.TIME
|
||||
|| v.getType() == IsoType.DATE12) {
|
||||
|| v.getType() == IsoType.DATE12 || v.getType() == IsoType.DATE14) {
|
||||
pos += (v.getLength() / 2) + (v.getLength() % 2);
|
||||
} else {
|
||||
pos += v.getLength();
|
||||
|
||||
@@ -0,0 +1,98 @@
|
||||
package com.solab.iso8583.parse;
|
||||
|
||||
import com.solab.iso8583.CustomField;
|
||||
import com.solab.iso8583.IsoType;
|
||||
import com.solab.iso8583.IsoValue;
|
||||
|
||||
import java.io.UnsupportedEncodingException;
|
||||
import java.text.ParseException;
|
||||
import java.util.Calendar;
|
||||
import java.util.Date;
|
||||
|
||||
/**
|
||||
* Blabla.
|
||||
*
|
||||
* @author Enrique Zamudio
|
||||
* Date: 06/01/16 10:52 AM
|
||||
*/
|
||||
public class Date14ParseInfo extends DateTimeParseInfo {
|
||||
|
||||
public Date14ParseInfo() {
|
||||
super(IsoType.DATE14, 14);
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T> IsoValue<Date> parse(final int field, final byte[] buf,
|
||||
final int pos, final CustomField<T> custom)
|
||||
throws ParseException, UnsupportedEncodingException {
|
||||
if (pos < 0) {
|
||||
throw new ParseException(String.format("Invalid DATE14 field %d position %d",
|
||||
field, pos), pos);
|
||||
}
|
||||
if (pos+14 > buf.length) {
|
||||
throw new ParseException(String.format("Insufficient data for DATE14 field %d, pos %d",
|
||||
field, pos), pos);
|
||||
}
|
||||
//A SimpleDateFormat in the case of dates won't help because of the missing data
|
||||
//we have to use the current date for reference and change what comes in the buffer
|
||||
Calendar cal = Calendar.getInstance();
|
||||
//Set the month in the date
|
||||
if (forceStringDecoding) {
|
||||
cal.set(Calendar.YEAR, Integer.parseInt(new String(buf, pos, 4, getCharacterEncoding()), 10));
|
||||
cal.set(Calendar.MONTH, Integer.parseInt(new String(buf, pos, 2, getCharacterEncoding()), 10)-1);
|
||||
cal.set(Calendar.DATE, Integer.parseInt(new String(buf, pos+2, 2, getCharacterEncoding()), 10));
|
||||
cal.set(Calendar.HOUR_OF_DAY, Integer.parseInt(new String(buf, pos+4, 2, getCharacterEncoding()), 10));
|
||||
cal.set(Calendar.MINUTE, Integer.parseInt(new String(buf, pos+6, 2, getCharacterEncoding()), 10));
|
||||
cal.set(Calendar.SECOND, Integer.parseInt(new String(buf, pos+8, 2, getCharacterEncoding()), 10));
|
||||
} else {
|
||||
cal.set(Calendar.YEAR, ((buf[pos] - 48) * 1000) + ((buf[pos + 1] - 48) * 100) + ((buf[pos + 2] - 48) * 10) + buf[pos + 3] - 48);
|
||||
cal.set(Calendar.MONTH, ((buf[pos+4] - 48) * 10) + buf[pos + 5] - 49);
|
||||
cal.set(Calendar.DATE, ((buf[pos + 6] - 48) * 10) + buf[pos + 7] - 48);
|
||||
cal.set(Calendar.HOUR_OF_DAY, ((buf[pos + 8] - 48) * 10) + buf[pos + 9] - 48);
|
||||
cal.set(Calendar.MINUTE, ((buf[pos + 10] - 48) * 10) + buf[pos + 11] - 48);
|
||||
cal.set(Calendar.SECOND, ((buf[pos + 12] - 48) * 10) + buf[pos + 13] - 48);
|
||||
}
|
||||
cal.set(Calendar.MILLISECOND,0);
|
||||
if (tz != null) {
|
||||
cal.setTimeZone(tz);
|
||||
}
|
||||
adjustWithFutureTolerance(cal);
|
||||
return new IsoValue<>(type, cal.getTime(), null);
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T> IsoValue<Date> parseBinary(final int field, final byte[] buf,
|
||||
final int pos, final CustomField<T> custom)
|
||||
throws ParseException {
|
||||
if (pos < 0) {
|
||||
throw new ParseException(String.format("Invalid DATE14 field %d position %d",
|
||||
field, pos), pos);
|
||||
}
|
||||
if (pos+7 > buf.length) {
|
||||
throw new ParseException(String.format("Insufficient data for DATE14 field %d, pos %d",
|
||||
field, pos), pos);
|
||||
}
|
||||
int[] tens = new int[7];
|
||||
int start = 0;
|
||||
for (int i = pos; i < pos + tens.length; i++) {
|
||||
tens[start++] = (((buf[i] & 0xf0) >> 4) * 10) + (buf[i] & 0x0f);
|
||||
}
|
||||
Calendar cal = Calendar.getInstance();
|
||||
//A SimpleDateFormat in the case of dates won't help because of the missing data
|
||||
//we have to use the current date for reference and change what comes in the buffer
|
||||
//Set the month in the date
|
||||
cal.set(Calendar.YEAR, (tens[0] * 100) + tens[1]);
|
||||
cal.set(Calendar.MONTH, tens[2] - 1);
|
||||
cal.set(Calendar.DATE, tens[3]);
|
||||
cal.set(Calendar.HOUR_OF_DAY, tens[4]);
|
||||
cal.set(Calendar.MINUTE, tens[5]);
|
||||
cal.set(Calendar.SECOND, tens[6]);
|
||||
cal.set(Calendar.MILLISECOND,0);
|
||||
if (tz != null) {
|
||||
cal.setTimeZone(tz);
|
||||
}
|
||||
adjustWithFutureTolerance(cal);
|
||||
return new IsoValue<>(type, cal.getTime(), null);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -113,6 +113,8 @@ public abstract class FieldParseInfo {
|
||||
fpi = new Date10ParseInfo();
|
||||
} else if (t == IsoType.DATE12) {
|
||||
fpi = new Date12ParseInfo();
|
||||
} else if (t == IsoType.DATE14) {
|
||||
fpi = new Date14ParseInfo();
|
||||
} else if (t == IsoType.DATE4) {
|
||||
fpi = new Date4ParseInfo();
|
||||
} else if (t == IsoType.DATE_EXP) {
|
||||
|
||||
@@ -22,6 +22,7 @@ public class TestFormats {
|
||||
Assert.assertEquals("7301", IsoType.DATE_EXP.format(date, null));
|
||||
Assert.assertEquals("213456", IsoType.TIME.format(date, null));
|
||||
Assert.assertEquals("730125213456", IsoType.DATE12.format(date, null));
|
||||
Assert.assertEquals("19730125213456", IsoType.DATE14.format(date, null));
|
||||
//Now with GMT
|
||||
TimeZone gmt = TimeZone.getTimeZone("GMT");
|
||||
Assert.assertEquals("0126033456", IsoType.DATE10.format(date, gmt));
|
||||
@@ -29,6 +30,7 @@ public class TestFormats {
|
||||
Assert.assertEquals("7301", IsoType.DATE_EXP.format(date, gmt));
|
||||
Assert.assertEquals("033456", IsoType.TIME.format(date, gmt));
|
||||
Assert.assertEquals("730126033456", IsoType.DATE12.format(date, gmt));
|
||||
Assert.assertEquals("19730126033456", IsoType.DATE14.format(date, gmt));
|
||||
//And now with GMT+1
|
||||
gmt = TimeZone.getTimeZone("GMT+0100");
|
||||
Assert.assertEquals("0126043456", IsoType.DATE10.format(date, gmt));
|
||||
@@ -36,6 +38,7 @@ public class TestFormats {
|
||||
Assert.assertEquals("7301", IsoType.DATE_EXP.format(date, gmt));
|
||||
Assert.assertEquals("043456", IsoType.TIME.format(date, gmt));
|
||||
Assert.assertEquals("730126043456", IsoType.DATE12.format(date, gmt));
|
||||
Assert.assertEquals("19730126043456", IsoType.DATE14.format(date, gmt));
|
||||
}
|
||||
|
||||
@Test
|
||||
|
||||
@@ -61,4 +61,17 @@ public class TestDates {
|
||||
Assert.assertEquals(comp.getValue().getTime(), bin.getValue().getTime());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testDate14FutureTolerance() throws ParseException, IOException {
|
||||
Date soon = new Date(System.currentTimeMillis() + 50000);
|
||||
byte[] buf = IsoType.DATE14.format(soon, null).getBytes();
|
||||
IsoValue<Date> comp = new Date14ParseInfo().parse(0, buf, 0, null);
|
||||
assert comp.getValue().after(new Date());
|
||||
//Now with the binary
|
||||
ByteArrayOutputStream bout = new ByteArrayOutputStream();
|
||||
comp.write(bout, true, false);
|
||||
IsoValue<Date> bin = new Date14ParseInfo().parseBinary(0, bout.toByteArray(), 0, null);
|
||||
Assert.assertEquals(comp.getValue().getTime(), bin.getValue().getTime());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user