package org.basex.query.item;
import static org.basex.query.QueryText.*;
import static org.basex.query.util.Err.*;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import org.basex.query.QueryException;
import org.basex.query.util.Err;
import org.basex.util.InputInfo;
import org.basex.util.Token;
import org.basex.util.TokenBuilder;
/**
* YearMonth Duration item.
*
* @author BaseX Team 2005-12, BSD License
* @author Christian Gruen
*/
public final class YMd extends Dur {
/** YearMonth pattern. */
private static final Pattern DUR = Pattern.compile(
"(-?)P(([0-9]+)Y)?(([0-9]+)M)?");
/**
* Constructor.
* @param it duration item
*/
YMd(final Dur it) {
super(AtomType.YMD);
mon = it.mon;
}
/**
* Constructor.
* @param it duration item
* @param a duration to be added/subtracted
* @param p plus/minus flag
*/
public YMd(final YMd it, final YMd a, final boolean p) {
this(it);
mon += p ? a.mon : -a.mon;
}
/**
* Constructor.
* @param it duration item
* @param f factor
* @param m multiplication/division flag
* @param ii input info
* @throws QueryException query exception
*/
public YMd(final Dur it, final double f, final boolean m, final InputInfo ii)
throws QueryException {
this(it);
if(Double.isNaN(f)) DATECALC.thrw(ii, description(), f);
if(m ? f == 1 / 0d || f == -1 / 0d : f == 0)
DATEZERO.thrw(ii, description());
mon = (int) StrictMath.round(m ? mon * f : mon / f);
}
/**
* Constructor.
* @param v value
* @param ii input info
* @throws QueryException query exception
*/
YMd(final byte[] v, final InputInfo ii) throws QueryException {
super(AtomType.YMD);
final String val = Token.string(v).trim();
final Matcher mt = DUR.matcher(val);
if(!mt.matches() || val.endsWith("P")) dateErr(v, XYMD, ii);
final int y = mt.group(2) != null ? Token.toInt(mt.group(3)) : 0;
final int m = mt.group(4) != null ? Token.toInt(mt.group(5)) : 0;
mon = y * 12 + m;
if(!mt.group(1).isEmpty()) mon = -mon;
}
/**
* Returns the years and months.
* @return year
*/
public int ymd() {
return mon;
}
@Override
public byte[] string(final InputInfo ii) {
final TokenBuilder tb = new TokenBuilder();
if(mon < 0) tb.add('-');
tb.add('P');
if(yea() != 0) { tb.addLong(Math.abs(yea())); tb.add('Y'); }
if(mon() != 0) { tb.addLong(Math.abs(mon())); tb.add('M'); }
if(mon == 0) tb.add("0M");
return tb.finish();
}
@Override
public int diff(final InputInfo ii, final Item it) throws QueryException {
if(it.type != type) Err.diff(ii, it, this);
return mon - ((Dur) it).mon;
}
}