package water.rapids.ast.prims.time; import org.joda.time.MutableDateTime; import water.MRTask; import water.fvec.Chunk; import water.fvec.Frame; import water.fvec.NewChunk; import water.fvec.Vec; import water.parser.ParseTime; import water.rapids.Env; import water.rapids.Val; import water.rapids.vals.ValFrame; import water.rapids.vals.ValNum; import water.rapids.ast.AstPrimitive; import water.rapids.ast.AstRoot; /** * Basic time accessors; extract hours/days/years/etc from H2O's internal * msec-since-Unix-epoch time */ public abstract class AstTime extends AstPrimitive { @Override public String[] args() { return new String[]{"time"}; } // (op time) @Override public int nargs() { return 1 + 1; } // Override for e.g. month and day-of-week protected String[][] factors() { return null; } public abstract long op(MutableDateTime dt); private double op(MutableDateTime dt, double d) { dt.setMillis((long) d); return op(dt); } @Override public Val apply(Env env, Env.StackHelp stk, AstRoot asts[]) { Val val = asts[1].exec(env); switch (val.type()) { case Val.NUM: double d = val.getNum(); return new ValNum(Double.isNaN(d) ? d : op(new MutableDateTime(0), d)); case Val.FRM: Frame fr = stk.track(val).getFrame(); if (fr.numCols() > 1) throw water.H2O.unimpl(); return new ValFrame(new MRTask() { @Override public void map(Chunk chk, NewChunk cres) { MutableDateTime mdt = new MutableDateTime(0, ParseTime.getTimezone()); for (int i = 0; i < chk._len; i++) cres.addNum(chk.isNA(i) ? Double.NaN : op(mdt, chk.at8(i))); } }.doAll(1, Vec.T_NUM, fr).outputFrame(fr._names, factors())); default: throw water.H2O.fail(); } } }