--- /dev/null
+/**
+ * Macaco
+ * Copyright (c) 2009-2012 Marco Zanon <info@marcozanon.com>.
+ * Released under MIT license (see LICENSE for details).
+ */
+
+package com.marcozanon.macaco.conversion;
+
+import com.marcozanon.macaco.MObject;
+import java.text.ParseException;
+import java.text.SimpleDateFormat;
+import java.util.Calendar;
+import java.util.Date;
+import java.util.Iterator;
+import java.util.LinkedHashSet;
+import java.util.Locale;
+import java.util.TimeZone;
+
+public class MDateConverter extends MObject {
+
+ protected LinkedHashSet<String> dateFormats = new LinkedHashSet<String>();
+ protected Locale locale = null;
+ protected TimeZone timeZone = null;
+
+ /* */
+
+ public MDateConverter(String defaultDateFormat, Locale locale) {
+ this(defaultDateFormat, locale, TimeZone.getTimeZone("UTC"));
+ }
+
+ public MDateConverter(String defaultDateFormat, Locale locale, TimeZone timeZone) {
+ super();
+ //
+ this.addDateFormat(defaultDateFormat);
+ this.setLocale(locale);
+ this.setTimeZone(timeZone);
+ }
+
+ public MDateConverter(LinkedHashSet<String> dateFormats, Locale locale, TimeZone timeZone) {
+ super();
+ //
+ this.setDateFormats(dateFormats);
+ this.setLocale(locale);
+ this.setTimeZone(timeZone);
+ }
+
+ public MDateConverter clone() {
+ return new MDateConverter(this.getDateFormats(), this.getLocale(), this.getTimeZone());
+ }
+
+ /* Date formats */
+
+ public void setDateFormats(LinkedHashSet<String> dateFormats) {
+ if (null == dateFormats) {
+ throw new IllegalArgumentException("Invalid 'dateFormats': null.");
+ }
+ else {
+ Iterator i = dateFormats.iterator();
+ while (i.hasNext()) {
+ MDateConverter.checkDateFormat((String)i.next());
+ }
+ }
+ //
+ synchronized (this.dateFormats) {
+ this.dateFormats = dateFormats;
+ }
+ }
+
+ public void addDateFormat(String dateFormat) {
+ MDateConverter.checkDateFormat(dateFormat);
+ //
+ synchronized (this.dateFormats) {
+ this.dateFormats.add(dateFormat);
+ }
+ }
+
+ protected LinkedHashSet<String> getDateFormatsReference() {
+ return this.dateFormats;
+ }
+
+ public LinkedHashSet<String> getDateFormats() {
+ LinkedHashSet<String> tmpDateFormats = new LinkedHashSet<String>();
+ Iterator i = this.getDateFormatsReference().iterator();
+ while (i.hasNext()) {
+ tmpDateFormats.add((String)i.next());
+ }
+ return tmpDateFormats;
+ }
+
+ public String getDefaultDateFormat() {
+ return this.getDateFormatsReference().iterator().next();
+ }
+
+ /* Locale */
+
+ protected void setLocale(Locale locale) {
+ if (null == locale) {
+ throw new IllegalArgumentException("Invalid 'locale': null.");
+ }
+ //
+ this.locale = locale;
+ }
+
+ protected Locale getLocaleReference() {
+ return this.locale;
+ }
+
+ public Locale getLocale() {
+ return (Locale)this.getLocaleReference().clone();
+ }
+
+ /* Time zone */
+
+ protected void setTimeZone(TimeZone timeZone) {
+ if (null == timeZone) {
+ throw new IllegalArgumentException("Invalid 'timeZone': null.");
+ }
+ //
+ this.timeZone = timeZone;
+ }
+
+ protected TimeZone getTimeZoneReference() {
+ return this.timeZone;
+ }
+
+ public TimeZone getTimeZone() {
+ return (TimeZone)this.getTimeZoneReference().clone();
+ }
+
+ /* Conversion */
+
+ protected static void checkDateFormat(String dateFormat) {
+ if ((null == dateFormat) || ("".equals(dateFormat))) {
+ throw new IllegalArgumentException("Invalid 'dateFormat': null or empty.");
+ }
+ //
+ try {
+ SimpleDateFormat testDateFormat = new SimpleDateFormat(dateFormat);
+ }
+ catch (IllegalArgumentException exception) {
+ throw new IllegalArgumentException(String.format("Invalid 'dateFormat': %s.", dateFormat)); // no need to propagate exception
+ }
+ }
+
+ protected static Date getDateFromStringByParameters(String x, String inputDateFormat, Locale inputLocale, TimeZone inputTimeZone) throws MFormatConversionException {
+ if ((null == x) || ("".equals(x))) {
+ throw new IllegalArgumentException("Invalid 'x': null or empty.");
+ }
+ MDateConverter.checkDateFormat(inputDateFormat);
+ if (null == inputLocale) {
+ throw new IllegalArgumentException("Invalid 'inputLocale': null.");
+ }
+ if (null == inputTimeZone) {
+ throw new IllegalArgumentException("Invalid 'inputTimeZone': null.");
+ }
+ //
+ Calendar c1 = Calendar.getInstance(inputTimeZone, inputLocale);
+ c1.clear();
+ c1.setLenient(false);
+ SimpleDateFormat sdf = new SimpleDateFormat(inputDateFormat, inputLocale);
+ sdf.setCalendar(c1);
+ Date d1 = null;
+ try {
+ d1 = sdf.parse(x);
+ }
+ catch (ParseException exception) {
+ throw new MFormatConversionException(String.format("Invalid 'x' or parsing: %s (input format: %s).", x, inputDateFormat)); // no need to propagate exception
+ }
+ Calendar c2 = Calendar.getInstance(inputTimeZone, inputLocale);
+ c2.clear();
+ c2.set(Calendar.YEAR, c1.get(Calendar.YEAR));
+ c2.set(Calendar.MONTH, c1.get(Calendar.MONTH));
+ c2.set(Calendar.DAY_OF_MONTH, c1.get(Calendar.DAY_OF_MONTH));
+ Date d2 = c2.getTime();
+ if (!x.equals(sdf.format(d2))) {
+ throw new MFormatConversionException(String.format("Invalid 'x' or parsing: %s (input format: %s).", x, inputDateFormat));
+ }
+ return d2;
+ }
+
+ protected static String getStringFromDateByParameters(Date date, String outputDateFormat, Locale outputLocale, TimeZone outputTimeZone) {
+ if (null == date) {
+ throw new IllegalArgumentException("Invalid 'date': null.");
+ }
+ MDateConverter.checkDateFormat(outputDateFormat);
+ if (null == outputLocale) {
+ throw new IllegalArgumentException("Invalid 'outputLocale': null.");
+ }
+ if (null == outputTimeZone) {
+ throw new IllegalArgumentException("Invalid 'outputTimeZone': null.");
+ }
+ //
+ SimpleDateFormat sdf = new SimpleDateFormat(outputDateFormat, outputLocale);
+ sdf.setCalendar(Calendar.getInstance(outputTimeZone, outputLocale));
+ return sdf.format(date);
+ }
+
+ public Date getDateFromString(String x) throws MFormatConversionException {
+ Date y = null;
+ for (String dateFormat: this.getDateFormatsReference()) {
+ try {
+ y = this.getDateFromStringByParameters(x, dateFormat, this.getLocaleReference(), this.getTimeZoneReference());
+ return y;
+ }
+ catch (MFormatConversionException exception) {
+ }
+ }
+ if (null == y) {
+ throw new MFormatConversionException(String.format("Invalid 'x': %s.", x));
+ }
+ return y; // necessary to avoid Java compilation errors
+ }
+
+ public String getStringFromDate(Date x) throws MFormatConversionException {
+ return this.getStringFromDateByParameters(x, this.getDefaultDateFormat(), this.getLocaleReference(), this.getTimeZoneReference());
+ }
+
+}
--- /dev/null
+/**
+ * Macaco
+ * Copyright (c) 2009-2012 Marco Zanon <info@marcozanon.com>.
+ * Released under MIT license (see LICENSE for details).
+ */
+
+package com.marcozanon.macaco.conversion;
+
+import com.marcozanon.macaco.MObject;
+import java.math.BigDecimal;
+import java.text.DecimalFormat;
+import java.text.DecimalFormatSymbols;
+import java.text.ParsePosition;
+import java.util.Iterator;
+import java.util.LinkedHashSet;
+import java.util.Locale;
+
+public class MNumberConverter extends MObject {
+
+ protected LinkedHashSet<String> numberFormats = new LinkedHashSet<String>();
+ protected Locale locale = null;
+
+ /* */
+
+ public MNumberConverter(String defaultNumberFormat, Locale locale) {
+ super();
+ //
+ this.addNumberFormat(defaultNumberFormat);
+ this.setLocale(locale);
+ }
+
+ public MNumberConverter(LinkedHashSet<String> numberFormats, Locale locale) {
+ super();
+ //
+ this.setNumberFormats(numberFormats);
+ this.setLocale(locale);
+ }
+
+ public MNumberConverter clone() {
+ return new MNumberConverter(this.getNumberFormats(), this.getLocale());
+ }
+
+ /* Number formats */
+
+ public void setNumberFormats(LinkedHashSet<String> numberFormats) {
+ if (null == numberFormats) {
+ throw new IllegalArgumentException("Invalid 'numberFormats': null.");
+ }
+ else {
+ Iterator i = numberFormats.iterator();
+ while (i.hasNext()) {
+ MNumberConverter.checkNumberFormat((String)i.next());
+ }
+ }
+ //
+ synchronized (this.numberFormats) {
+ this.numberFormats = numberFormats;
+ }
+ }
+
+ public void addNumberFormat(String numberFormat) {
+ MNumberConverter.checkNumberFormat(numberFormat);
+ //
+ synchronized (this.numberFormats) {
+ this.numberFormats.add(numberFormat);
+ }
+ }
+
+ protected LinkedHashSet<String> getNumberFormatsReference() {
+ return this.numberFormats;
+ }
+
+ public LinkedHashSet<String> getNumberFormats() {
+ LinkedHashSet<String> tmpNumberFormats = new LinkedHashSet<String>();
+ Iterator i = this.getNumberFormatsReference().iterator();
+ while (i.hasNext()) {
+ tmpNumberFormats.add((String)i.next());
+ }
+ return tmpNumberFormats;
+ }
+
+ public String getDefaultNumberFormat() {
+ return this.getNumberFormatsReference().iterator().next();
+ }
+
+ /* Locale */
+
+ protected void setLocale(Locale locale) {
+ if (null == locale) {
+ throw new IllegalArgumentException("Invalid 'locale': null.");
+ }
+ //
+ this.locale = locale;
+ }
+
+ protected Locale getLocaleReference() {
+ return this.locale;
+ }
+
+ public Locale getLocale() {
+ return (Locale)this.getLocaleReference().clone();
+ }
+
+ /* Conversion */
+
+ protected static void checkNumberFormat(String numberFormat) {
+ if ((null == numberFormat) || ("".equals(numberFormat))) {
+ throw new IllegalArgumentException("Invalid 'numberFormat': null or empty.");
+ }
+ //
+ try {
+ DecimalFormat testNumberFormat = new DecimalFormat(numberFormat);
+ }
+ catch (IllegalArgumentException exception) {
+ throw new IllegalArgumentException(String.format("Invalid 'numberFormat': %s.", numberFormat)); // no need to propagate exception
+ }
+ }
+
+ protected static BigDecimal getNumberFromStringByParameters(String x, String inputNumberFormat, Locale inputLocale) throws MFormatConversionException {
+ if ((null == x) || ("".equals(x))) {
+ throw new IllegalArgumentException("Invalid 'x': null or empty.");
+ }
+ MNumberConverter.checkNumberFormat(inputNumberFormat);
+ if (null == inputLocale) {
+ throw new IllegalArgumentException("Invalid 'inputLocale': null.");
+ }
+ //
+ DecimalFormatSymbols dfs = new DecimalFormatSymbols(inputLocale);
+ DecimalFormat df = new DecimalFormat(inputNumberFormat, dfs);
+ df.setParseBigDecimal(true);
+ ParsePosition validPosition = new ParsePosition(0);
+ BigDecimal bd = (BigDecimal)df.parse(x, validPosition);
+ if (validPosition.getIndex() < x.length()) {
+ throw new MFormatConversionException(String.format("Invalid 'x' or parsing: %s (input format: %s).", x, inputNumberFormat));
+ }
+ return bd;
+ }
+
+ protected static String getStringFromNumberByParameters(BigDecimal number, String outputNumberFormat, Locale outputLocale) {
+ if (null == number) {
+ throw new IllegalArgumentException("Invalid 'number': null.");
+ }
+ MNumberConverter.checkNumberFormat(outputNumberFormat);
+ if (null == outputLocale) {
+ throw new IllegalArgumentException("Invalid 'outputLocale': null.");
+ }
+ //
+ DecimalFormatSymbols dfs = new DecimalFormatSymbols(outputLocale);
+ DecimalFormat df = new DecimalFormat(outputNumberFormat, dfs);
+ return df.format(number);
+ }
+
+ public BigDecimal getNumberFromString(String x) throws MFormatConversionException {
+ BigDecimal y = null;
+ for (String numberFormat: this.getNumberFormatsReference()) {
+ try {
+ y = this.getNumberFromStringByParameters(x, numberFormat, this.getLocaleReference());
+ return y;
+ }
+ catch (MFormatConversionException exception) {
+ }
+ }
+ if (null == y) {
+ throw new MFormatConversionException(String.format("Invalid 'x': %s.", x));
+ }
+ return y; // necessary to avoid Java compilation errors
+ }
+
+ public String getStringFromNumber(BigDecimal x) throws MFormatConversionException {
+ return this.getStringFromNumberByParameters(x, this.getDefaultNumberFormat(), this.getLocaleReference());
+ }
+
+}