1
0
mirror of https://github.com/gnosygnu/xowa.git synced 2024-09-29 23:10:52 +00:00

ParserFunctions: Support next / previous for day of week [#262]

This commit is contained in:
gnosygnu 2018-11-18 23:04:59 -05:00
parent 50d1fbfed1
commit 2e5994788f
9 changed files with 207 additions and 96 deletions

View File

@ -66,10 +66,20 @@ public class Pft_func_time__basic__tst {
@Test public void Unit_rel_year_next() {fxt.Test_parse_tmpl_str("{{#time:Y-m-d|next year}}" , "2013-01-02");} // DATE:2014-05-02
@Test public void Unit_rel_year_last() {fxt.Test_parse_tmpl_str("{{#time:Y-m-d|last year}}" , "2011-01-02");}
@Test public void Unit_rel_year_previous(){fxt.Test_parse_tmpl_str("{{#time:Y-m-d|previous year}}" , "2011-01-02");}
@Test public void Unit_rel_month_next() {fxt.Test_parse_tmpl_str("{{#time:Y-m-d|next month}}" , "2012-02-02");}
@Test public void Unit_rel_month_prev() {fxt.Test_parse_tmpl_str("{{#time:Y-m-d|previous month}}" , "2011-12-02");}
@Test public void Unit_rel_year_this() {fxt.Test_parse_tmpl_str("{{#time:Y-m-d|this year}}" , "2012-01-02");}
@Test public void Time_rel_now() {fxt.Test_parse_tmpl_str("{{#time:Y-m-d h:i:s A|now}}" , "2012-01-02 03:05:05 AM");} // NOTE: minute is 5, not 4, b/c each call to Datetime_now.Get() automatically increments by 1 minute; DATE:2014-04-13
@Test public void Empty_is_today() {fxt.Test_parse_tmpl_str("{{#time:Y-m-d|}}" , "2012-01-02");} // tested on MW
@Test public void Day_name_today() {fxt.Test_parse_tmpl_str("{{#time:Y-m-d|Monday}}" , "2012-01-02");} // 2012-01-02 is Monday, so return Monday; DATE:2014-05-02
@Test public void Day_monday_none() {fxt.Test_parse_tmpl_str("{{#time:Y-m-d|Monday}}" , "2012-01-02");} // 2012-01-02 is Monday, so return Monday; DATE:2014-05-02
@Test public void Day_monday_this() {fxt.Test_parse_tmpl_str("{{#time:Y-m-d|this Monday}}" , "2012-01-02");} // "this Monday" is same as "Monday"
@Test public void Day_monday_next() {fxt.Test_parse_tmpl_str("{{#time:Y-m-d|next Monday}}" , "2012-01-09");}
@Test public void Day_monday_prev() {fxt.Test_parse_tmpl_str("{{#time:Y-m-d|previous Monday}}" , "2011-12-26");}
@Test public void Day_sunday_none() {fxt.Test_parse_tmpl_str("{{#time:Y-m-d|Sunday}}" , "2012-01-08");}
@Test public void Day_sunday_this() {fxt.Test_parse_tmpl_str("{{#time:Y-m-d|this Sunday}}" , "2012-01-08");}
@Test public void Day_sunday_next() {fxt.Test_parse_tmpl_str("{{#time:Y-m-d|next Sunday}}" , "2012-01-15");}
@Test public void Day_sunday_prev() {fxt.Test_parse_tmpl_str("{{#time:Y-m-d|previous Sunday}}" , "2012-01-01");}
@Test public void Day_relative_smoke() {fxt.Test_parse_tmpl_str("{{#time:Y-m-d|6 april next sunday}}" , "2012-04-15");}
@Test public void Day_name_future_1() {fxt.Test_parse_tmpl_str("{{#time:Y-m-d|Saturday}}" , "2012-01-07");} // return next Sunday; DATE:2014-05-02
@Test public void Day_name_future_2() {fxt.Test_parse_tmpl_str("{{#time:Y-m-d|Sunday}}" , "2012-01-08");} // return next Saturday; DATE:2014-05-02
@Test public void Day_name_dow() {fxt.Test_parse_tmpl_str("{{#time:w|Monday}}" , "1");}

View File

@ -0,0 +1,36 @@
/*
XOWA: the XOWA Offline Wiki Application
Copyright (C) 2012-2017 gnosygnu@gmail.com
XOWA is licensed under the terms of the General Public License (GPL) Version 3,
or alternatively under the terms of the Apache License Version 2.0.
You may use XOWA according to either of these licenses as is most appropriate
for your project on a case-by-case basis.
The terms of each license can be found in the source code repository:
GPLv3 License: https://github.com/gnosygnu/xowa/blob/master/LICENSE-GPLv3.txt
Apache License: https://github.com/gnosygnu/xowa/blob/master/LICENSE-APACHE2.txt
*/
package gplx.xowa.xtns.pfuncs.times; import gplx.*; import gplx.xowa.*; import gplx.xowa.xtns.*; import gplx.xowa.xtns.pfuncs.*;
public class Pxd_date_bldr {
private int[] seg_ary;
public Pxd_date_bldr(int year, int month, int day, int hour, int minute, int second, int frac) {
this.seg_ary = new int[] {year, month, day, hour, minute, second, frac};
}
// most workers will just set individual segments
public void Seg_set(int idx, int val) {
seg_ary[idx] = val;
}
// relative workers will convert segs to date, add a relative unit, and then convert back to date
// note that the date conversion is necessary b/c Date class has logic to do things like "2017-12-31 +1 day" and rollover to next month / next year
public DateAdp To_date() {
return DateAdp_.seg_(seg_ary);
}
public void By_date(DateAdp v) {
this.seg_ary = v.XtoSegAry();
}
}

View File

@ -22,7 +22,7 @@ interface Pxd_itm {
int Eval_idx();
int Data_idx(); void Data_idx_(int v);
boolean Eval(Pxd_parser state);
boolean Time_ini(DateAdpBldr bldr);
boolean Time_ini(Pxd_date_bldr bldr);
}
class Pxd_itm_ {
public static final int
@ -46,7 +46,16 @@ class Pxd_itm_ {
, Tid_colon = Byte_ascii.Colon
, Tid_ws = 98
, Tid_sym = 99
;
;
public static Pxd_itm Find_fwd__non_ws(Pxd_itm[] tkns, int bgn) {
int len = tkns.length;
for (int i = bgn; i < len; i++) {
Pxd_itm itm = tkns[i];
if (itm.Tkn_tid() != Tid_ws) return itm;
}
return null;
}
public static Pxd_itm Find_bwd__non_ws(Pxd_itm[] tkns, int bgn) {
for (int i = bgn - 1; i > -1; --i) {
Pxd_itm itm = tkns[i];
@ -73,38 +82,13 @@ abstract class Pxd_itm_base implements Pxd_itm {
public int Data_idx() {return data_idx;} public void Data_idx_(int v) {data_idx = v;} private int data_idx;
public abstract int Eval_idx();
@gplx.Virtual public boolean Eval(Pxd_parser state) {return true;}
@gplx.Virtual public boolean Time_ini(DateAdpBldr bldr) {return true;}
@gplx.Virtual public boolean Time_ini(Pxd_date_bldr bldr) {return true;}
public void Ctor(int ary_idx) {this.ary_idx = ary_idx;}
public static final int Seg_idx_null = -1, Seg_idx_skip = -2;
}
interface Pxd_itm_prototype {
Pxd_itm MakeNew(int ary_idx);
}
class DateAdpBldr {
public DateAdp Date() {
if (dirty) {
if (date == null) date = DateAdp_.seg_(seg_ary); // date not set and seg_ary is dirty; make date = seg_ary;
return date;
}
else
return Datetime_now.Get(); // not dirtied; default to now;
}
public DateAdpBldr Date_(DateAdp v) {date = v; return this;} DateAdp date = null;
public void Seg_set(int idx, int val) {
if (date == null) seg_ary[idx] = val;
else {
seg_ary = date.XtoSegAry();
seg_ary[idx] = val;
date = DateAdp_.seg_(seg_ary);
}
dirty = true;
}
public DateAdp Bld() {
return date == null ? DateAdp_.seg_(seg_ary) : date;
}
public DateAdpBldr(int... seg_ary) {this.seg_ary = seg_ary;}
int[] seg_ary = new int[DateAdp_.SegIdx__max]; boolean dirty = false;
}
class Pft_func_time_log {
private static final Gfo_msg_grp owner = Gfo_msg_grp_.new_(Xoa_app_.Nde, "time_parser");
public static final Gfo_msg_itm

View File

@ -0,0 +1,55 @@
/*
XOWA: the XOWA Offline Wiki Application
Copyright (C) 2012-2017 gnosygnu@gmail.com
XOWA is licensed under the terms of the General Public License (GPL) Version 3,
or alternatively under the terms of the Apache License Version 2.0.
You may use XOWA according to either of these licenses as is most appropriate
for your project on a case-by-case basis.
The terms of each license can be found in the source code repository:
GPLv3 License: https://github.com/gnosygnu/xowa/blob/master/LICENSE-GPLv3.txt
Apache License: https://github.com/gnosygnu/xowa/blob/master/LICENSE-APACHE2.txt
*/
package gplx.xowa.xtns.pfuncs.times; import gplx.*; import gplx.xowa.*; import gplx.xowa.xtns.*; import gplx.xowa.xtns.pfuncs.*;
class Pxd_itm_dow_name extends Pxd_itm_base implements Pxd_itm_prototype {
private final int dow_idx;
private final byte[] dow_name;
private int relative_adj = Int_.Max_value;
public Pxd_itm_dow_name(int ary_idx, byte[] dow_name, int dow_idx) {
this.dow_name = dow_name;
this.dow_idx = dow_idx;
this.Ctor(ary_idx);
this.Seg_idx_(DateAdp_.SegIdx_dayOfWeek);
}
@Override public byte Tkn_tid() {return Pxd_itm_.Tid_dow_name;}
@Override public int Eval_idx() {return 20;}
public Pxd_itm MakeNew(int ary_idx) {return new Pxd_itm_dow_name(ary_idx, dow_name, dow_idx);}
public void Relative_adj_(int v) { // handled by relative_word; EX: "next tuesday"
this.relative_adj = v;
}
@Override public boolean Eval(Pxd_parser state) {return true;}
@Override public boolean Time_ini(Pxd_date_bldr bldr) {
DateAdp cur = bldr.To_date();
int cur_dow = cur.DayOfWeek();
// adj = requested_dow - cur_dow; EX: requesting Friday, and today is Wednesday; adj = 2 (4 - 2); DATE:2014-05-02
int adj = dow_idx - cur.DayOfWeek();
// requested_dow is before cur_dow; add 7 to get the next day
if (adj < 0) adj += 7;
// "next" always adds 7 days
if (relative_adj == 1)
adj += 7;
// "previous" always subtracts 7 days;
else if (relative_adj == -1)
adj -= 7;
cur = cur.Add_day(adj);
bldr.By_date(cur);
return true;
}
}

View File

@ -41,27 +41,28 @@ class Pxd_itm_int extends Pxd_itm_base implements Pxd_itm_int_interface {
public boolean Val_is_adj() {return val_is_adj;} public void Val_is_adj_(boolean v) {val_is_adj = v;} private boolean val_is_adj;
public int Xto_int_or(int or) {return val;}
public int Digits() {return digits;} private int digits;
@Override public boolean Time_ini(DateAdpBldr bldr) {
@Override public boolean Time_ini(Pxd_date_bldr bldr) {
int seg_idx = this.Seg_idx();
if (seg_idx == Pxd_itm_base.Seg_idx_skip) return true;
if (val_is_adj) {
if (val == 0) return true; // no adjustment to make
DateAdp date = bldr.Date();
DateAdp date = bldr.To_date();
switch (seg_idx) {
case DateAdp_.SegIdx_hour: date = date.Add_hour(val); break;
case DateAdp_.SegIdx_minute: date = date.Add_minute(val); break;
default: return true;
}
bldr.Date_(date);
bldr.By_date(date);
}
else {
if (val == 0) { // 0 means subtract 1; EX:w:Mariyinsky_Palace; DATE:2014-03-25
DateAdp date = bldr.Date();
DateAdp date = bldr.To_date();
switch (seg_idx) {
case DateAdp_.SegIdx_month: date = DateAdp_.seg_(new int[] {date.Year(), 1, date.Day(), date.Hour(), date.Minute(), date.Second(), date.Frac()}).Add_month(-1); bldr.Date_(date); break;
case DateAdp_.SegIdx_day: date = DateAdp_.seg_(new int[] {date.Year(), date.Month(), 1, date.Hour(), date.Minute(), date.Second(), date.Frac()}).Add_day(-1); bldr.Date_(date); break;
case DateAdp_.SegIdx_month: date = DateAdp_.seg_(new int[] {date.Year(), 1, date.Day(), date.Hour(), date.Minute(), date.Second(), date.Frac()}).Add_month(-1); break;
case DateAdp_.SegIdx_day: date = DateAdp_.seg_(new int[] {date.Year(), date.Month(), 1, date.Hour(), date.Minute(), date.Second(), date.Frac()}).Add_day(-1); break;
default: return true;
}
bldr.By_date(date);
}
else {
if (seg_idx == -1) return false; // PAGE:New_York_City EX: March 14, 2,013; DATE:2016-07-06

View File

@ -79,7 +79,7 @@ class Pxd_itm_slash extends Pxd_itm_base {
class Pxd_itm_sym extends Pxd_itm_base {
@Override public byte Tkn_tid() {return Pxd_itm_.Tid_sym;}
@Override public int Eval_idx() {return 99;}
@Override public boolean Time_ini(DateAdpBldr bldr) {return true;}
@Override public boolean Time_ini(Pxd_date_bldr bldr) {return true;}
public byte Sym_byte() {return sym_byte;} private byte sym_byte;
public Pxd_itm_sym(int ary_idx, byte val) {this.Ctor(ary_idx); this.sym_byte = val;}
}
@ -88,7 +88,7 @@ class Pxd_itm_int_dmy_14 extends Pxd_itm_base implements Pxd_itm_int_interface {
public int Xto_int_or(int or) {return Bry_.To_int_or(src, or);}
@Override public byte Tkn_tid() {return Pxd_itm_.Tid_int_dmy_14;}
@Override public int Eval_idx() {return eval_idx;} private int eval_idx = 20;
@Override public boolean Time_ini(DateAdpBldr bldr) {
@Override public boolean Time_ini(Pxd_date_bldr bldr) {
if (this.Seg_idx() != Pxd_itm_base.Seg_idx_null) return true; // has seg_idx; already eval'd by something else
bldr.Seg_set(DateAdp_.SegIdx_year , Bry_.To_int_or(src, 0, 4, 0));
bldr.Seg_set(DateAdp_.SegIdx_month , Bry_.To_int_or(src, 4, 6, 0));
@ -111,7 +111,7 @@ class Pxd_itm_int_mhs_6 extends Pxd_itm_base implements Pxd_itm_int_interface {
public int Xto_int_or(int or) {return Bry_.To_int_or(src, or);}
@Override public byte Tkn_tid() {return Pxd_itm_.Tid_int_hms_6;}
@Override public int Eval_idx() {return eval_idx;} private int eval_idx = 20;
@Override public boolean Time_ini(DateAdpBldr bldr) {
@Override public boolean Time_ini(Pxd_date_bldr bldr) {
if (this.Seg_idx() != Pxd_itm_base.Seg_idx_null) return true; // has seg_idx; already eval'd by something else
bldr.Seg_set(DateAdp_.SegIdx_hour , Bry_.To_int_or(src, 0, 2, 0));
bldr.Seg_set(DateAdp_.SegIdx_minute , Bry_.To_int_or(src, 2, 4, 0));

View File

@ -16,10 +16,16 @@ Apache License: https://github.com/gnosygnu/xowa/blob/master/LICENSE-APACHE2.txt
package gplx.xowa.xtns.pfuncs.times; import gplx.*; import gplx.xowa.*; import gplx.xowa.xtns.*; import gplx.xowa.xtns.pfuncs.*;
import gplx.core.brys.*;
class Pxd_itm_month_name extends Pxd_itm_base implements Pxd_itm_prototype {
public Pxd_itm_month_name(int ary_idx, byte[] name, int seg_idx, int seg_val) {Ctor(ary_idx); this.name = name; Seg_idx_(seg_idx); this.seg_val = seg_val;} private byte[] name;
private byte[] name;
private int seg_val;
public Pxd_itm_month_name(int ary_idx, byte[] name, int seg_idx, int seg_val) {
Ctor(ary_idx);
this.name = name;
Seg_idx_(seg_idx);
this.seg_val = seg_val;
}
@Override public byte Tkn_tid() {return Pxd_itm_.Tid_month_name;}
@Override public int Eval_idx() {return 20;}
int seg_val;
public Pxd_itm MakeNew(int ary_idx) {
Pxd_itm_month_name rv = new Pxd_itm_month_name(ary_idx, name, this.Seg_idx(), seg_val);
return rv;
@ -142,7 +148,7 @@ class Pxd_itm_month_name extends Pxd_itm_base implements Pxd_itm_prototype {
}
}
}
@Override public boolean Time_ini(DateAdpBldr bldr) {
@Override public boolean Time_ini(Pxd_date_bldr bldr) {
bldr.Seg_set(this.Seg_idx(), seg_val);
return true;
}
@ -202,9 +208,8 @@ class Pxd_itm_unit extends Pxd_itm_base implements Pxd_itm_prototype {
}
return true;
}
@Override public boolean Time_ini(DateAdpBldr bldr) {
DateAdp cur = bldr.Date();
if (cur == null) cur = Datetime_now.Get();
@Override public boolean Time_ini(Pxd_date_bldr bldr) {
DateAdp cur = bldr.To_date();
int val = seg_val * seg_multiple;
switch (this.Seg_idx()) {
case DateAdp_.SegIdx_second: cur = cur.Add_second(val); break;
@ -215,7 +220,7 @@ class Pxd_itm_unit extends Pxd_itm_base implements Pxd_itm_prototype {
case DateAdp_.SegIdx_year : cur = cur.Add_year (val); break;
default: throw Err_.new_unhandled(this.Seg_idx());
}
bldr.Date_(cur);
bldr.By_date(cur);
return true;
}
}
@ -246,7 +251,7 @@ class Pxd_itm_ago extends Pxd_itm_base implements Pxd_itm_prototype {
}
return true;
}
@Override public boolean Time_ini(DateAdpBldr bldr) {return true;}
@Override public boolean Time_ini(Pxd_date_bldr bldr) {return true;}
}
class Pxd_itm_day_suffix extends Pxd_itm_base implements Pxd_itm_prototype {
public Pxd_itm_day_suffix(int ary_idx) {Ctor(ary_idx);}
@ -271,7 +276,7 @@ class Pxd_itm_day_relative extends Pxd_itm_base implements Pxd_itm_prototype {
@Override public int Eval_idx() {return 5;}
public Pxd_itm MakeNew(int ary_idx) {return new Pxd_itm_day_relative(adj, ary_idx);}
@Override public boolean Eval(Pxd_parser state) {return true;}
@Override public boolean Time_ini(DateAdpBldr bldr) {
@Override public boolean Time_ini(Pxd_date_bldr bldr) {
DateAdp date = Datetime_now.Get();
if (adj != 0) date = date.Add_day(adj);
bldr.Seg_set(DateAdp_.SegIdx_year , date.Year());
@ -293,7 +298,7 @@ class Pxd_itm_time_relative extends Pxd_itm_base implements Pxd_itm_prototype {
@Override public int Eval_idx() {return 5;}
public Pxd_itm MakeNew(int ary_idx) {return new Pxd_itm_time_relative(ary_idx);}
@Override public boolean Eval(Pxd_parser state) {return true;}
@Override public boolean Time_ini(DateAdpBldr bldr) {
@Override public boolean Time_ini(Pxd_date_bldr bldr) {
DateAdp date = Datetime_now.Get();
bldr.Seg_set(DateAdp_.SegIdx_year , date.Year());
bldr.Seg_set(DateAdp_.SegIdx_month , date.Month());
@ -309,34 +314,6 @@ class Pxd_itm_time_relative extends Pxd_itm_base implements Pxd_itm_prototype {
;
Pxd_itm_time_relative() {}
}
class Pxd_itm_unit_relative extends Pxd_itm_base implements Pxd_itm_prototype { // EX: "next year"
private final int adj;
public Pxd_itm_unit_relative(int adj, int ary_idx) {
Ctor(ary_idx);
this.adj = adj;
}
@Override public byte Tkn_tid() {return Pxd_itm_.Tid_unit_relative;}
@Override public int Eval_idx() {return 5;}
public Pxd_itm MakeNew(int ary_idx) {return new Pxd_itm_unit_relative(adj, ary_idx);}
@Override public boolean Eval(Pxd_parser state) {
// find next token: EX: sec, hour, day, fortnight, month, etc.
Pxd_itm itm = Pxd_itm_.Find_fwd_by_tid(state.Tkns(), this.Ary_idx() + 1, Pxd_itm_.Tid_unit);
if (itm == null) state.Err_set(Pft_func_time_log.Invalid_date, Bfr_arg_.New_int(adj));
// cast to unit; may fail; EX:update in "last update" as per "March 2006 [last update]";PAGE:s.w:Synesthesia;DATE:2016-07-06
Pxd_itm_unit unit_tkn = (Pxd_itm_unit)itm;
if (unit_tkn == null) {state.Err_set(Pft_func_time_log.Invalid_date, Bfr_arg_.New_int(adj)); return false;}
unit_tkn.Unit_seg_val_(adj);
return true;
}
@Override public boolean Time_ini(DateAdpBldr bldr) {return true;}
public static final Pxd_itm_unit_relative
Next = new Pxd_itm_unit_relative( 1, 0)
, Prev = new Pxd_itm_unit_relative(-1, 0)
, This = new Pxd_itm_unit_relative( 0, 0)
;
}
class Pxd_itm_unixtime extends Pxd_itm_base implements Pxd_itm_prototype {
private long unixtime;
public Pxd_itm_unixtime(int ary_idx, int seg_idx) {Ctor(ary_idx); Seg_idx_(seg_idx);}
@ -349,7 +326,7 @@ class Pxd_itm_unixtime extends Pxd_itm_base implements Pxd_itm_prototype {
unixtime = Pxd_itm_int_.Read_nearest_as_int_and_skip(state, tkns, this.Ary_idx(), true, Int_.Min_value);
return true;
}
@Override public boolean Time_ini(DateAdpBldr bldr) {
@Override public boolean Time_ini(Pxd_date_bldr bldr) {
DateAdp date = DateAdp_.unixtime_utc_seconds_(unixtime);
bldr.Seg_set(DateAdp_.SegIdx_year , date.Year());
bldr.Seg_set(DateAdp_.SegIdx_month , date.Month());
@ -361,22 +338,6 @@ class Pxd_itm_unixtime extends Pxd_itm_base implements Pxd_itm_prototype {
return true;
}
}
class Pxd_itm_dow_name extends Pxd_itm_base implements Pxd_itm_prototype {
private int dow_idx;
private byte[] dow_name;
public Pxd_itm_dow_name(int ary_idx, byte[] dow_name, int dow_idx) {Ctor(ary_idx); this.dow_name = dow_name; this.Seg_idx_(DateAdp_.SegIdx_dayOfWeek); this.dow_idx = dow_idx;}
@Override public byte Tkn_tid() {return Pxd_itm_.Tid_dow_name;}
@Override public int Eval_idx() {return 20;}
public Pxd_itm MakeNew(int ary_idx) {return new Pxd_itm_dow_name(ary_idx, dow_name, dow_idx);}
@Override public boolean Eval(Pxd_parser state) {return true;}
@Override public boolean Time_ini(DateAdpBldr bldr) {
DateAdp now = Datetime_now.Get();
int adj = dow_idx - now.DayOfWeek(); // adj = requested_dow - current_dow; EX: requesting Friday, and today is Wednesday; adj = 2 (4 - 2); DATE:2014-05-02
if (adj < 0) adj += 7; // requested_down is before current_dow; add 7 to get the next day
bldr.Date_(bldr.Date().Add_day(adj));
return true;
}
}
class Pxd_itm_iso8601_t extends Pxd_itm_base implements Pxd_itm_prototype {
public Pxd_itm_iso8601_t(int ary_idx, int seg_idx) {Ctor(ary_idx); Seg_idx_(seg_idx);}
public byte[] Name() {return Name_const;} public static final byte[] Name_const = Bry_.new_a7("T");
@ -389,7 +350,7 @@ class Pxd_itm_iso8601_t extends Pxd_itm_base implements Pxd_itm_prototype {
state.Err_set(Pft_func_time_log.Invalid_hour, Bfr_arg_.New_bry("T"));
return true;
}
@Override public boolean Time_ini(DateAdpBldr bldr) {return true;}
@Override public boolean Time_ini(Pxd_date_bldr bldr) {return true;}
private static Pxd_itm Next_non_ws_tkn(Pxd_itm[] tkns, int bgn) {
int len = tkns.length;
for (int i = bgn; i < len; i++) {

View File

@ -0,0 +1,62 @@
/*
XOWA: the XOWA Offline Wiki Application
Copyright (C) 2012-2017 gnosygnu@gmail.com
XOWA is licensed under the terms of the General Public License (GPL) Version 3,
or alternatively under the terms of the Apache License Version 2.0.
You may use XOWA according to either of these licenses as is most appropriate
for your project on a case-by-case basis.
The terms of each license can be found in the source code repository:
GPLv3 License: https://github.com/gnosygnu/xowa/blob/master/LICENSE-GPLv3.txt
Apache License: https://github.com/gnosygnu/xowa/blob/master/LICENSE-APACHE2.txt
*/
package gplx.xowa.xtns.pfuncs.times; import gplx.*; import gplx.xowa.*; import gplx.xowa.xtns.*; import gplx.xowa.xtns.pfuncs.*;
import gplx.core.brys.*;
class Pxd_itm_unit_relative extends Pxd_itm_base implements Pxd_itm_prototype { // handle "next", "prev", "this"; EX: "next year"
private final int adj;
public Pxd_itm_unit_relative(int adj, int ary_idx) {
this.adj = adj;
Ctor(ary_idx);
}
@Override public byte Tkn_tid() {return Pxd_itm_.Tid_unit_relative;}
@Override public int Eval_idx() {return 5;}
public Pxd_itm MakeNew(int ary_idx) {return new Pxd_itm_unit_relative(adj, ary_idx);}
@Override public boolean Eval(Pxd_parser state) {
// find next token: EX: year, month, Sunday, Monday, etc.
Pxd_itm itm = Pxd_itm_.Find_fwd__non_ws(state.Tkns(), this.Ary_idx() + 1);
if (itm == null) {
state.Err_set(Pft_func_time_log.Invalid_date, Bfr_arg_.New_int(adj));
return false;
}
switch (itm.Tkn_tid()) {
// EX: "next year", "next month", etc.
case Pxd_itm_.Tid_unit:
Pxd_itm_unit unit_tkn = (Pxd_itm_unit)itm;
unit_tkn.Unit_seg_val_(adj);
break;
// EX: "next Monday", "next Tuesday", etc.
case Pxd_itm_.Tid_dow_name:
Pxd_itm_dow_name day_tkn = (Pxd_itm_dow_name)itm;
day_tkn.Relative_adj_(adj);
break;
default:
state.Err_set(Pft_func_time_log.Invalid_date, Bfr_arg_.New_int(adj));
return false;
}
return true;
}
@Override public boolean Time_ini(Pxd_date_bldr bldr) {
// noop; date-logic handled by respective unit, month, dow classes; EX: "next month" -> "next" does no date logic; "month" does;
return true;
}
public static final Pxd_itm_unit_relative
Next = new Pxd_itm_unit_relative( 1, 0)
, Prev = new Pxd_itm_unit_relative(-1, 0)
, This = new Pxd_itm_unit_relative( 0, 0)
;
}

View File

@ -143,8 +143,10 @@ class Pxd_parser {
return DateAdp_.MinValue;
}
}
// build date
DateAdp now = Datetime_now.Get();
DateAdpBldr bldr = new DateAdpBldr(now.Year(), now.Month(), now.Day(), 0, 0, 0, 0);
Pxd_date_bldr bldr = new Pxd_date_bldr(now.Year(), now.Month(), now.Day(), 0, 0, 0, 0);
for (int i = 0; i < tkns_len; i++) {
Pxd_itm itm = (Pxd_itm)tkns[i];
if (!itm.Time_ini(bldr)) {
@ -152,7 +154,7 @@ class Pxd_parser {
return null;
}
}
return bldr.Bld();
return bldr.To_date();
}
private void MakeDataAry() {
data_ary = new Pxd_itm[tkns_len]; data_ary_len = 0;