com.prowidesoftware.swift.utils.SwiftFormatUtils Maven / Gradle / Ivy
Show all versions of pw-swift-core Show documentation
/*
* Copyright 2006-2023 Prowide
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.prowidesoftware.swift.utils;
import com.prowidesoftware.swift.model.BIC;
import com.prowidesoftware.swift.model.LogicalTerminalAddress;
import com.prowidesoftware.swift.model.MIR;
import com.prowidesoftware.swift.model.MOR;
import java.math.BigDecimal;
import java.text.DecimalFormat;
import java.text.DecimalFormatSymbols;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Currency;
import java.util.Date;
import java.util.GregorianCalendar;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.time.DateFormatUtils;
/**
* This class provides methods to convert field components to objects.
* It handles for example; dates, currencies and general functions defined in the SWIFT standard.
*
* - DATE1 MMDD
* - DATE2 YYMMDD
* - DATE3 YYMM
* - DATE4 YYYYMMDD
* - YEAR YYYY
* - AMOUNT ###,### (digits with comma as decimal separator)
* - TIME2 HHmmss
* - TIME3 HH[mm]
* - BOOL Y/N
* - DATETIME YYYYMMDDHHMM
* - DATETIME with short year YYMMDDHHMM
* - DAYTIME DDHHMM
* - MONTHDAY MMDD
* - MIR
* - MOR
*
*
* @author sebastian
* @since 6.0
*/
public class SwiftFormatUtils {
private static final transient java.util.logging.Logger log =
java.util.logging.Logger.getLogger(SwiftFormatUtils.class.getName());
// Suppress default constructor for noninstantiability
private SwiftFormatUtils() {
throw new AssertionError();
}
/**
* Parses a DATE2 string (accept dates in format YYMMDD) into a Calendar object.
*
* @param strDate string to parse
* @return parsed date or null if the argument did not matched the expected date format
*/
public static Calendar getDate2(final String strDate) {
if (strDate != null && strDate.length() == 6) {
return getCalendar(strDate, "yyMMdd");
} else {
return null;
}
}
/**
* Parses a Calendar object into a DATE2 string.
*
* @param date Calendar to parse
* @return parsed date or null if the calendar is null
*/
public static String getDate2(final Calendar date) {
return getCalendar(date, "yyMMdd");
}
/**
* Parses a DATE1 string (accept dates in format MMDD) into a Calendar object.
*
* @param strDate string to parse
* @return parsed date or null if the argument did not matched the expected date format
* @see #getMonthDay(String)
*/
public static Calendar getDate1(final String strDate) {
return getMonthDay(strDate);
}
/**
* returns true if the parameter year is a leap year
*
* @since 7.8.8
*/
public static boolean isLeapYear(int year) {
Calendar cal = Calendar.getInstance();
cal.set(Calendar.YEAR, year);
return cal.getActualMaximum(Calendar.DAY_OF_YEAR) > 365;
}
/**
* Parses a Calendar object into a DATE1 string.
*
* @param date Calendar to parse
* @return parsed date or null if the calendar is null
* @see #getMonthDay(Calendar)
* @since 6.4
*/
public static String getDate1(final Calendar date) {
return getMonthDay(date);
}
/**
* Parses a DATE3 string (accept dates in format YYMM) into a Calendar object.
*
* @param strDate string to parse
* @return parsed date or null if the argument did not matched the expected date format
*/
public static Calendar getDate3(final String strDate) {
if (strDate != null && strDate.length() == 4) {
return getCalendar(strDate, "yyMM");
} else {
return null;
}
}
/**
* Parses a Calendar object into a DATE1 string.
*
* @param date Calendar to parse
* @return parsed date or null if the calendar is null
* @since 6.4
*/
public static String getDate3(final Calendar date) {
return getCalendar(date, "yyMM");
}
/**
* Parses a DATE4 string (accept dates in format YYYYMMDD) into a Calendar object.
*
* @param strDate string to parse
* @return parsed date or null if the argument did not matched the expected date format
*/
public static Calendar getDate4(final String strDate) {
if (strDate != null && strDate.length() == 8) {
return getCalendar(strDate, "yyyyMMdd");
} else {
return null;
}
}
/**
* Parses a Calendar object into a DATE1 string.
*
* @param date Calendar to parse
* @return parsed date or null if the calendar is null
* @since 6.4
*/
public static String getDate4(final Calendar date) {
return getCalendar(date, "yyyyMMdd");
}
/**
* Parses a YEAR string (accept dates in format YYYY) into a Calendar object.
*
* @param strDate string to parse
* @return parsed date or null if the argument did not matched the expected date format
*/
public static Calendar getYear(final String strDate) {
if (strDate != null && strDate.length() == 4) {
return getCalendar(strDate, "yyyy");
} else {
return null;
}
}
/**
* Parses a Calendar object into a YYYY string.
*
* @param date Calendar to parse
* @return parsed date or null if the calendar is null
* @since 6.4
*/
public static String getYear(final Calendar date) {
return getCalendar(date, "yyyy");
}
/**
* Parses a value into a java Number (BigDecimal) using the comma for decimal separator.
*
* @param value to parse
* @return Long of the parsed value or null if the number could not be parsed
*/
public static Long getLong(final String value) {
Long number = null;
if (value != null) {
try {
number = Long.valueOf(value);
} catch (final NumberFormatException e) {
log.log(java.util.logging.Level.WARNING, "Error parsing number", e);
}
}
return number;
}
/**
* Converts a Long into a SWIFT string number
*
* @param number to convert
* @return String representation of the converted number
*/
public static String getLong(final Long number) {
return number != null ? number.toString() : null;
}
/**
* Parses a value into a java Number (BigDecimal) using the comma for decimal separator.
*
* @param amount to parse
* @return Number of the parsed amount or null if the number could not be parsed
*/
public static Number getNumber(final String amount) {
Number number = null;
if (amount != null) {
try {
final DecimalFormatSymbols symbols = new DecimalFormatSymbols();
symbols.setDecimalSeparator(',');
final DecimalFormat df = new DecimalFormat("00.##", symbols);
df.setParseBigDecimal(true);
number = df.parse(amount);
} catch (final ParseException e) {
log.log(java.util.logging.Level.WARNING, "Error parsing number", e);
}
}
return number;
}
/**
* Parses a Number into a SWIFT string number ####,## with truncated zero decimals and mandatory decimal separator.
*
* - Example: 1234.00 -> 1234,
* - Example: 1234 -> 1234,
* - Example: 1234.56 -> 1234,56
*
*
* @param number to parse
* @return Number of the parsed amount or null if the number is null
*/
public static String getNumber(final Number number) {
if (number != null) {
final DecimalFormatSymbols symbols = new DecimalFormatSymbols();
symbols.setDecimalSeparator(',');
final DecimalFormat df = new DecimalFormat("0.##########", symbols);
df.setParseBigDecimal(true);
df.setDecimalSeparatorAlwaysShown(true);
final String formatted = df.format(number);
return StringUtils.replaceChars(formatted, '.', ',');
}
return null;
}
/**
* Parses a value into a java Number (BigDecimal) using the comma for decimal separator.
*
* @param amount to parse
* @return Number of the parsed amount or null if the number could not be parsed
*/
public static BigDecimal getBigDecimal(final String amount) {
BigDecimal bigDecimal = null;
if (amount != null) {
try {
final DecimalFormatSymbols symbols = new DecimalFormatSymbols();
symbols.setDecimalSeparator(',');
final DecimalFormat df = new DecimalFormat("00.##", symbols);
df.setParseBigDecimal(true);
bigDecimal = (BigDecimal) df.parse(amount);
} catch (final ParseException e) {
log.log(java.util.logging.Level.WARNING, "Error parsing number", e);
}
}
return bigDecimal;
}
/**
* Parses a Number into a SWIFT string number ####,## with truncated zero decimals and mandatory decimal separator.
*
* - Example: 1234.00 -> 1234,
* - Example: 1234 -> 1234,
* - Example: 1234.56 -> 1234,56
*
*
* @param bigDecimal to parse
* @return Number of the parsed amount or null if the number is null
*/
public static String getBigDecimal(final BigDecimal bigDecimal) {
if (bigDecimal != null) {
final DecimalFormatSymbols symbols = new DecimalFormatSymbols();
symbols.setDecimalSeparator(',');
final DecimalFormat df = new DecimalFormat("0.##########", symbols);
df.setParseBigDecimal(true);
df.setDecimalSeparatorAlwaysShown(true);
final String formatted = df.format(bigDecimal);
return StringUtils.replaceChars(formatted, '.', ',');
}
return null;
}
/**
* Converts the given time into a Calendar.
* Only the time information is set, the date will be the default 1/1/70
*
* @param hhmm hour and minutes
* @return a Calendar set with the given hour and minutes
*/
public static Calendar getHhmm(final String hhmm) {
if (hhmm != null && hhmm.length() == 4) {
return getCalendar(hhmm, "HHmm");
} else {
return null;
}
}
private static Calendar getCalendar(final String value, final String format) {
if (value != null) {
try {
final SimpleDateFormat sdf = new SimpleDateFormat(format);
sdf.setLenient(false);
final Date d = sdf.parse(value);
final Calendar cal = new GregorianCalendar();
cal.setTime(d);
return cal;
} catch (final ParseException e) {
log.log(
java.util.logging.Level.WARNING,
"Could not parse '" + value + "' with pattern '" + format + "'");
}
}
return null;
}
/**
* @since 6.4
*/
private static String getCalendar(final Calendar date, final String format) {
if (date != null) {
return DateFormatUtils.format(date.getTime(), format);
}
return null;
}
/**
* Converts the given time into a Calendar.
* Only the time information is set, the date will be the default 1/1/70
*
* @param hhmmss hour, minutes and seconds
* @return a Calendar set with the given hour, minutes and seconds
*/
public static Calendar getTime2(final String hhmmss) {
if (hhmmss != null && hhmmss.length() == 6) {
return getCalendar(hhmmss, "HHmmss");
} else {
return null;
}
}
/**
* Parses a Calendar object into a TIME2 string.
*
* @param date Calendar to parse
* @return parsed time or null if the calendar is null
* @since 6.4
*/
public static String getTime2(final Calendar date) {
return getCalendar(date, "HHmmss");
}
/**
* Converts the given time into a Calendar.
* Only the time information is set, the date will be the default 1/1/70
*
* @param hhmmss hour, minutes and seconds
* @return a Calendar set with the given hour, or and hour and minutes
*/
public static Calendar getTime3(final String hhmmss) {
if (hhmmss != null) {
if (hhmmss.length() == 2) {
return getCalendar(hhmmss, "HH");
} else if (hhmmss.length() == 4) {
return getCalendar(hhmmss, "HHmm");
}
}
return null;
}
/**
* Parses a Calendar object into a TIME3 string.
*
* @param date Calendar to parse
* @return parsed time or null if the calendar is null
* @since 6.4
*/
public static String getTime3(final Calendar date) {
return getCalendar(date, "HHmm");
}
/**
* @param string with a single character
* @return the Character for the given string
*/
public static Character getSign(final String string) {
if (StringUtils.isNotEmpty(string)) {
return string.charAt(0);
}
return null;
}
/**
* @param string with an offset
* @return a Calendar set with hour and minutes from the offset
*/
public static Calendar getOffset(final String string) {
return getHhmm(string);
}
/**
* Parses a Calendar object into a offset string.
*
* @param date Calendar to parse
* @return parsed time or null if the calendar is null
* @since 6.4
*/
public static String getOffset(final Calendar date) {
return getCalendar(date, "HHmm");
}
/**
* Returns the Currency
instance for the given currency code.
*
* @param code string with a currency code
* @return a Currency initialized from the parameter code or null if parameter code is null
* @throws IllegalArgumentException if currencyCode is not a supported ISO 4217 code.
*/
public static Currency getCurrency(final String code) {
if (code != null) {
return Currency.getInstance(code);
} else {
return null;
}
}
/**
* Gets the currency code from the parameter Currency.
*
* @param currency Currency to use
* @return the string with the currency code
* @since 6.4
*/
public static String getCurrency(final Currency currency) {
return currency.getCurrencyCode();
}
/**
* @param code string with a BIC code
* @return a BIC initialized from the parameter code
*/
public static BIC getBIC(final String code) {
return new BIC(code);
}
/**
* Gets the code from the parameter BIC.
* If branch is present, returns a BIC11, otherwise returns a BIC8.
*
* @param bic BIC to use
* @return the string with the BIC code
* @since 6.4
*/
public static String getBIC(final BIC bic) {
if (StringUtils.isBlank(bic.getBranch())) {
return bic.getBic8();
} else {
return bic.getBic11();
}
}
/**
* Gets the given string as boolean.
*
* @param string code to use where the expected values are "Y" or "N"
* @return true for "Y", false for "N", and null otherwise
* @since 7.4
*/
public static Boolean getBoolean(final String string) {
if (string == null) {
return null;
}
if ("Y".equals(string)) {
return Boolean.TRUE;
}
if ("N".equals(string)) {
return Boolean.FALSE;
}
return null;
}
/**
* Parses a Boolean object into a string.
*
* @param bool Boolean to parse
* @return parsed boolean converted to "Y" or "N" or null if the boolean object is null
* @since 7.4
*/
public static String getBoolean(final Boolean bool) {
if (bool == null) {
return null;
}
return bool ? "Y" : "N";
}
/**
* Parses a DATETIME string (accepts dates with time in YYYYMMDDHHMM format) into a Calendar object.
*
* @param strDate string to parse
* @return parsed date or null if the argument did not matched the expected date format
* @since 7.4
*/
public static Calendar getDateTime(final String strDate) {
if (strDate != null && strDate.length() == 12) {
return getCalendar(strDate, "yyyyMMddHHmm");
} else {
return null;
}
}
/**
* Parses a Calendar object into a string containing the DATETIME with YYYYMMDDHHMM format.
*
* @param date Calendar to parse
* @return parsed date or null if the calendar is null
* @since 7.4
*/
public static String getDateTime(final Calendar date) {
return getCalendar(date, "yyyyMMddHHmm");
}
/**
* Parses a DATETIME with short year string (accepts dates with time in YYMMDDHHMM format) into a Calendar object.
*
* @param strDate string to parse
* @return parsed date or null if the argument did not matched the expected date format
* @since 7.4
*/
public static Calendar getDateTimeShortYear(final String strDate) {
if (strDate != null && strDate.length() == 10) {
return getCalendar(strDate, "yyMMddHHmm");
} else {
return null;
}
}
/**
* Parses a Calendar object into a DATETIME with short year string in YYMMDDHHMM format.
*
* @param date Calendar to parse
* @return parsed date or null if the calendar is null
* @since 7.4
*/
public static String getDateTimeShortYear(final Calendar date) {
return getCalendar(date, "yyMMddHHmm");
}
/**
* Parses a DAYTIME string (accepts dates with time in DDHHMM format) into a Calendar object.
*
* @param strDate string to parse
* @return parsed date or null if the argument did not matched the expected date format
* @since 7.4
*/
public static Calendar getDayTime(final String strDate) {
if (strDate != null && strDate.length() == 6) {
return getCalendar(strDate, "ddHHmm");
} else {
return null;
}
}
/**
* Parses a Calendar object into a string containing the DAYTIME in DDHHMM format.
*
* @param date Calendar to parse
* @return parsed date or null if the calendar is null
* @since 7.4
*/
public static String getDayTime(final Calendar date) {
return getCalendar(date, "ddHHmm");
}
/**
* Parses a MONTHDAY string (accepts dates in MMDD format) into a Calendar object.
* The year is set to the current year.
* The implementation will log a warning and return null if 0229 is passed as argument and the current year is not
* a leap year.
*
* @param strDate string to parse
* @return parsed date or null if the argument did not matched the expected date format
* @since 7.4
*/
public static Calendar getMonthDay(final String strDate) {
if (strDate != null && strDate.length() == 4) {
String year = String.valueOf(Calendar.getInstance().get(Calendar.YEAR));
return getCalendar(year + strDate, "yyyyMMdd");
} else {
return null;
}
}
/**
* Parses a Calendar object into a string containing MONTHDAY in MMDD format.
* For February 29 it will return null if current year is not a leap year.
*
* @param date Calendar to parse
* @return parsed date or null if the calendar is null
* @since 7.4
*/
public static String getMonthDay(final Calendar date) {
return getCalendar(date, "MMdd");
}
/**
* Parses an HOUR string (accepts time in HH format) into a Calendar object.
*
* @param strDate string to parse
* @return parsed date or null if the argument did not matched the expected date format
* @since 7.4
*/
public static Calendar getHour(final String strDate) {
if (strDate != null && strDate.length() == 2) {
return getCalendar(strDate, "HH");
} else {
return null;
}
}
/**
* Parses a Calendar object into a string containing the HOUR in HH format.
*
* @param date Calendar to parse
* @return parsed date or null if the calendar is null
* @since 7.4
*/
public static String getHour(final Calendar date) {
return getCalendar(date, "HH");
}
/**
* Parses a string value into a MIR object.
*
* @param value string containing the complete MIR value
* @return a MIR object containing the parsed data or null if the argument is not a 28 length string with a proper MIR data
* @see com.prowidesoftware.swift.model.MIR
*/
public static MIR getMIR(final String value) {
if (value != null && value.length() == 28) {
return new MIR(value);
} else {
return null;
}
}
/**
* Parses a MIR object into a string containing its serialized data.
*
* @param mir MIR to process
* @return serialized content of the MIR object or null if the parameter is empty or null
* @see MIR#getMIR()
* @since 7.4
*/
public static String getMIR(final MIR mir) {
if (mir != null) {
return mir.getMIR();
} else {
return null;
}
}
/**
* Parses a string value into a MOR object.
*
* @param value string containing the complete MOR value
* @return a MOR object containing the parsed data or null if the argument is not a 28 length string with a proper MOR data
* @see com.prowidesoftware.swift.model.MOR
*/
public static MOR getMOR(final String value) {
if (value != null && value.length() == 28) {
return new MOR(value);
} else {
return null;
}
}
/**
* Parses a MOR object into a string containing its serialized data.
*
* @param mor MOR to process
* @return serialized content of the MOR object or null if the parameter is empty or null
* @see MOR#getMOR()
* @since 7.4
*/
public static String getMOR(final MOR mor) {
if (mor != null) {
return mor.getMOR();
} else {
return null;
}
}
/**
* Return the number of decimals for a string with a swift formatted amount.
*
* @param amountString may be null or empty, in which case this method returns 0
* @return the number of digits after the last , or 0 in any other case.
* @since 7.8
*/
public static int decimalsInAmount(final String amountString) {
if (StringUtils.isNotEmpty(amountString)) {
final String tail = StringUtils.trim(StringUtils.substringAfterLast(amountString, ","));
return tail.length();
}
return 0;
}
/**
* Return the number of decimals for the given number, which can be null, in which case this method returns zero.
*
* @return the number of decimal in the number or zero if there are none or the amount is null
* @since 7.8
*/
public static int decimalsInAmount(final BigDecimal amount) {
if (amount != null && amount.scale() != 0) {
return amount.scale();
}
return 0;
}
/**
* @param address string with a LT identifier code (12 chars) composed by the
* BIC, LT identifier and branch.
* @return a LT address initialized from the parameter code
* @since 7.8.8
*/
public static LogicalTerminalAddress getLTAddress(final String address) {
return new LogicalTerminalAddress(address);
}
/**
* Gets the code from the parameter LogicalTerminalAddress.
* If the address is not complete, it will be filled with default values
* using {@link LogicalTerminalAddress#getSenderLogicalTerminalAddress()}
*
* @param address LT address to use
* @return the string with the full 12 characters long LT identifier
* @since 7.8.8
*/
public static String getLTAddress(final LogicalTerminalAddress address) {
return address.getSenderLogicalTerminalAddress();
}
}