/* * Copyright (c) 2011 Denis Solonenko. * All rights reserved. This program and the accompanying materials * are made available under the terms of the GNU Public License v2.0 * which accompanies this distribution, and is available at * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html */ package ru.orangesoftware.financisto2.export.qif; import android.util.Log; import java.math.BigDecimal; import java.text.NumberFormat; import java.text.ParseException; import java.util.Calendar; import java.util.Date; import java.util.regex.Pattern; import static ru.orangesoftware.financisto2.export.qif.QifDateFormat.*; import static ru.orangesoftware.financisto2.utils.Utils.isNotEmpty; /** * Created by IntelliJ IDEA. * User: Denis Solonenko * Date: 10/12/11 11:40 PM */ public class QifUtils { private static final Pattern DATE_DELIMITER_PATTERN = Pattern.compile("/|'|\\.|-"); private static final Pattern MONEY_PREFIX_PATTERN = Pattern.compile("\\D"); private static final BigDecimal HUNDRED = new BigDecimal(100); public static String trimFirstChar(String s) { return s.length() > 1 ? s.substring(1) : ""; } /** * Adopted from http://jgnash.svn.sourceforge.net/viewvc/jgnash/jgnash2/trunk/src/jgnash/imports/qif/QifUtils.java * * Converts a string into a data object * <p> * <p/> * format "6/21' 1" -> 6/21/2001 format "6/21'01" -> 6/21/2001 format "9/18'2001 -> 9/18/2001 format "06/21/2001" * format "06/21/01" format "3.26.03" -> German version of quicken format "03-26-2005" -> MSMoney format format * "1.1.2005" -> kmymoney2 20.1.94 European dd/mm/yyyy has been confirmed * <p/> * 21/2/07 -> 02/21/2007 UK, Quicken 2007 D15/2/07 * * @param sDate String QIF date to parse * @param format String identifier of format to parse * @return Returns parsed date and current date if an error occurs */ public static Date parseDate(String sDate, QifDateFormat format) { Calendar cal = Calendar.getInstance(); int month = cal.get(Calendar.MONTH); int day = cal.get(Calendar.DAY_OF_MONTH); int year = cal.get(Calendar.YEAR); String[] chunks = DATE_DELIMITER_PATTERN.split(sDate); if (format == US_FORMAT) { try { month = Integer.parseInt(chunks[0].trim()); day = Integer.parseInt(chunks[1].trim()); year = Integer.parseInt(chunks[2].trim()); } catch (Exception e) { //eat it Log.e("QifUtils", "Unable to parse US date", e); } } else if (format == EU_FORMAT) { try { day = Integer.parseInt(chunks[0].trim()); month = Integer.parseInt(chunks[1].trim()); year = Integer.parseInt(chunks[2].trim()); } catch (Exception e) { Log.e("QifUtils", "Unable to parse EU date", e); } } else { Log.e("QifUtils", "Invalid date format specified"); return new Date(); } if (year < 100) { if (year < 29) { year += 2000; } else { year += 1900; } } cal.set(year, month - 1, day, 0, 0, 0); cal.set(Calendar.MILLISECOND, 0); return cal.getTime(); } /** * Adopted from http://jgnash.svn.sourceforge.net/viewvc/jgnash/jgnash2/trunk/src/jgnash/imports/qif/QifUtils.java */ public static long parseMoney(String money) { if (money != null) { BigDecimal bdMoney; money = money.trim(); // to be safe try { bdMoney = new BigDecimal(money); return moneyAsLong(bdMoney); } catch (NumberFormatException e) { /* there must be commas, etc in the number. Need to look for them * and remove them first, and then try BigDecimal again. If that * fails, then give up and use NumberFormat and scale it down * */ String[] split = MONEY_PREFIX_PATTERN.split(money); if (split.length > 1) { StringBuilder buf = new StringBuilder(); if (money.startsWith("-")) { buf.append('-'); } for (int i = 0; i < split.length - 1; i++) { buf.append(split[i]); } buf.append('.'); buf.append(split[split.length - 1]); try { bdMoney = new BigDecimal(buf.toString()); return moneyAsLong(bdMoney); } catch (final NumberFormatException e2) { Log.e("QifUtils", "Second parse attempt failed, falling back to rounding"); } } NumberFormat formatter = NumberFormat.getNumberInstance(); try { Number num = formatter.parse(money); BigDecimal bd = new BigDecimal(num.floatValue()); if (bd.scale() > 6) { bd = bd.setScale(2, BigDecimal.ROUND_HALF_UP); } return moneyAsLong(bd); } catch (ParseException ignored) { } Log.e("QifUtils", "Could not parse money " + money); } } return 0; } private static long moneyAsLong(BigDecimal bd) { return bd.multiply(HUNDRED).intValue(); } public static boolean isTransferCategory(String category) { return isNotEmpty(category) && category.startsWith("[") && category.endsWith("]"); } }