fix #45 add DATE12

This commit is contained in:
Enrique Zamudio
2016-01-06 11:05:44 -06:00
parent a0c8413171
commit ab1d882476
9 changed files with 142 additions and 10 deletions

View File

@@ -60,7 +60,9 @@ public enum IsoType {
/** variable length with 4-digit header length. */
LLLLVAR(false, 0),
/** variable length byte array with 4-digit header length. */
LLLLBIN(false, 0);
LLLLBIN(false, 0),
/** Date in format yyMMddHHmmss. */
DATE12(false,12);
private boolean needsLen;
private int length;
@@ -80,7 +82,7 @@ public enum IsoType {
return length;
}
/** Formats a Date if the receiver is DATE10, DATE4, DATE_EXP or TIME; throws an exception
/** Formats a Date if the receiver is DATE10, DATE4, DATE_EXP, DATE12 or TIME; throws an exception
* otherwise. */
public String format(final Date value, final TimeZone tz) {
final SimpleDateFormat sdf;
@@ -92,6 +94,8 @@ public enum IsoType {
sdf = new SimpleDateFormat("yyMM");
} else if (this == TIME) {
sdf = new SimpleDateFormat("HHmmss");
} else if (this == DATE12) {
sdf = new SimpleDateFormat("yyMMddHHmmss");
} else {
throw new IllegalArgumentException("Cannot format date as " + this);
}

View File

@@ -333,7 +333,8 @@ public class IsoValue<T> implements Cloneable {
buf = new byte[(length / 2) + (length % 2)];
} else if (type == IsoType.AMOUNT) {
buf = new byte[6];
} else if (type == IsoType.DATE10 || type == IsoType.DATE4 || type == IsoType.DATE_EXP || type == IsoType.TIME) {
} else if (type == IsoType.DATE10 || type == IsoType.DATE4 ||
type == IsoType.DATE_EXP || type == IsoType.TIME || type == IsoType.DATE12) {
buf = new byte[length / 2];
}
//Encode in BCD if it's one of these types

View File

@@ -446,7 +446,7 @@ 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.DATE4 || val.getType() == IsoType.DATE12
|| val.getType() == IsoType.DATE_EXP
|| val.getType() == IsoType.AMOUNT
|| val.getType() == IsoType.TIME) {

View File

@@ -86,7 +86,8 @@ public class CompositeField implements CustomBinaryField<CompositeField> {
if (v != null) {
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.AMOUNT || v.getType() == IsoType.TIME
|| v.getType() == IsoType.DATE12) {
pos += (v.getLength() / 2) + (v.getLength() % 2);
} else {
pos += v.getLength();

View File

@@ -0,0 +1,108 @@
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 Date12ParseInfo extends DateTimeParseInfo {
public Date12ParseInfo() {
super(IsoType.DATE12, 12);
}
@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 DATE12 field %d position %d",
field, pos), pos);
}
if (pos+12 > buf.length) {
throw new ParseException(String.format("Insufficient data for DATE12 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
int year;
if (forceStringDecoding) {
year = Integer.parseInt(new String(buf, pos, 2, 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 {
year = ((buf[pos] - 48) * 10) + buf[pos + 1] - 48;
cal.set(Calendar.MONTH, ((buf[pos+2] - 48) * 10) + buf[pos + 3] - 49);
cal.set(Calendar.DATE, ((buf[pos + 4] - 48) * 10) + buf[pos + 5] - 48);
cal.set(Calendar.HOUR_OF_DAY, ((buf[pos + 6] - 48) * 10) + buf[pos + 7] - 48);
cal.set(Calendar.MINUTE, ((buf[pos + 8] - 48) * 10) + buf[pos + 9] - 48);
cal.set(Calendar.SECOND, ((buf[pos + 10] - 48) * 10) + buf[pos + 11] - 48);
}
if (year > 50) {
cal.set(Calendar.YEAR, 1900+year);
} else {
cal.set(Calendar.YEAR, 2000+year);
}
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 DATE12 field %d position %d",
field, pos), pos);
}
if (pos+6 > buf.length) {
throw new ParseException(String.format("Insufficient data for DATE12 field %d, pos %d",
field, pos), pos);
}
int[] tens = new int[6];
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
if (tens[0] > 50) {
cal.set(Calendar.YEAR, 1900+tens[0]);
} else {
cal.set(Calendar.YEAR, 2000+tens[0]);
}
cal.set(Calendar.MONTH, tens[1] - 1);
cal.set(Calendar.DATE, tens[2]);
cal.set(Calendar.HOUR_OF_DAY, tens[3]);
cal.set(Calendar.MINUTE, tens[4]);
cal.set(Calendar.SECOND, tens[5]);
cal.set(Calendar.MILLISECOND,0);
if (tz != null) {
cal.setTimeZone(tz);
}
adjustWithFutureTolerance(cal);
return new IsoValue<>(type, cal.getTime(), null);
}
}

View File

@@ -111,6 +111,8 @@ public abstract class FieldParseInfo {
fpi = new BinaryParseInfo(len);
} else if (t == IsoType.DATE10) {
fpi = new Date10ParseInfo();
} else if (t == IsoType.DATE12) {
fpi = new Date12ParseInfo();
} else if (t == IsoType.DATE4) {
fpi = new Date4ParseInfo();
} else if (t == IsoType.DATE_EXP) {

View File

@@ -215,7 +215,7 @@ public class TestConfigParser {
Assert.assertEquals(IsoType.AMOUNT.getLength(), field4.getLength());
// check nested field num 4 from composite field 62
CompositeField compositeField62 = (CompositeField) isoMessage.<Object>getField(62).getValue();
CompositeField compositeField62 = isoMessage.<CompositeField>getField(62).getValue();
IsoValue<Object> nestedField4 = compositeField62.getField(0); // first in list
Assert.assertEquals(IsoType.ALPHA, nestedField4.getType());
Assert.assertEquals(13, nestedField4.getLength());

View File

@@ -17,22 +17,25 @@ public class TestFormats {
@Test
public void testDateFormats() {
assert IsoType.DATE10.format(date, null).equals("0125213456");
assert IsoType.DATE4.format(date, null).equals("0125");
assert IsoType.DATE_EXP.format(date, null).equals("7301");
assert IsoType.TIME.format(date, null).equals("213456");
Assert.assertEquals("0125213456", IsoType.DATE10.format(date, null));
Assert.assertEquals("0125", IsoType.DATE4.format(date, null));
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));
//Now with GMT
TimeZone gmt = TimeZone.getTimeZone("GMT");
Assert.assertEquals("0126033456", IsoType.DATE10.format(date, gmt));
Assert.assertEquals("0126", IsoType.DATE4.format(date, gmt));
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));
//And now with GMT+1
gmt = TimeZone.getTimeZone("GMT+0100");
Assert.assertEquals("0126043456", IsoType.DATE10.format(date, gmt));
Assert.assertEquals("0126", IsoType.DATE4.format(date, gmt));
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));
}
@Test

View File

@@ -48,4 +48,17 @@ public class TestDates {
Assert.assertEquals(comp.getValue().getTime(), bin.getValue().getTime());
}
@Test
public void testDate12FutureTolerance() throws ParseException, IOException {
Date soon = new Date(System.currentTimeMillis() + 50000);
byte[] buf = IsoType.DATE12.format(soon, null).getBytes();
IsoValue<Date> comp = new Date12ParseInfo().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 Date12ParseInfo().parseBinary(0, bout.toByteArray(), 0, null);
Assert.assertEquals(comp.getValue().getTime(), bin.getValue().getTime());
}
}