static dt_ymd_t __daisy_to_ymd(dt_daisy_t that) { dt_daisy_t j00; unsigned int doy; unsigned int y; struct __md_s md; if (UNLIKELY(that == 0)) { return (dt_ymd_t){.u = 0}; } y = __daisy_get_year(that); j00 = __jan00_daisy(y); doy = that - j00; md = __yday_get_md(y, doy); #if defined HAVE_ANON_STRUCTS_INIT return (dt_ymd_t){.y = y, .m = md.m, .d = md.d}; #else /* !HAVE_ANON_STRUCTS_INIT */ { dt_ymd_t res; res.y = y; res.m = md.m; res.d = md.d; return res; } #endif /* HAVE_ANON_STRUCTS_INIT */ } static dt_ymcw_t __daisy_to_ymcw(dt_daisy_t that) { dt_ymd_t tmp; unsigned int c; unsigned int w; if (UNLIKELY(that == 0)) { return (dt_ymcw_t){.u = 0}; } tmp = __daisy_to_ymd(that); c = __ymd_get_count(tmp); w = __daisy_get_wday(that); #if defined HAVE_ANON_STRUCTS_INIT return (dt_ymcw_t){.y = tmp.y, .m = tmp.m, .c = c, .w = w}; #else { dt_ymcw_t res; res.y = tmp.y; res.m = tmp.m; res.c = c; res.w = w; return res; } #endif } static dt_ywd_t __daisy_to_ywd(dt_daisy_t that) { unsigned int wk = (that + 6) / 7; unsigned int wd = (that + 6) % 7; unsigned int y; unsigned int yw; dt_ywd_t res; /* get an estimate for the year and readjust */ y = __daisy_get_year(that); /* get the cumulative week count */ if (UNLIKELY((yw = wk - __get_cumwk(y)) == 0)) { y--; yw = __get_isowk(y); } else if (UNLIKELY(yw > __get_isowk(y))) { /* hanging over into the new year */ yw = 1U; y++; } /* final assignment */ res.y = y; res.c = yw; res.w = (wd + 1U) % 7U; return res; } #endif /* ASPECT_CONV */ #if defined ASPECT_ADD && !defined DAISY_ASPECT_ADD_ #define DAISY_ASPECT_ADD_ #define ASPECT_GETTERS #include "daisy.c" #undef ASPECT_GETTERS static dt_daisy_t __daisy_add_d(dt_daisy_t d, int n) { /* add N days to D */ d += n; return d; } static dt_daisy_t __daisy_add_b(dt_daisy_t d, int n) { /* add N business days to D */ dt_dow_t dow = __daisy_get_wday(d); int equ = __get_d_equiv(dow, n); d += equ; return d; }
static struct dt_d_s dround_ddur(struct dt_d_s d, struct dt_ddur_s dur, bool nextp) { switch (dur.durtyp) { unsigned int tgt; bool forw; case DT_DURD: if (dur.dv > 0) { tgt = dur.dv; forw = true; } else if (dur.dv < 0) { tgt = -dur.dv; forw = false; } else { /* user is an idiot */ break; } switch (d.typ) { unsigned int mdays; case DT_YMD: if ((forw && d.ymd.d < tgt) || (!forw && d.ymd.d > tgt)) { /* no month or year adjustment */ ; } else if (d.ymd.d == tgt && !nextp) { /* we're ON the date already and no * next/prev date is requested */ ; } else if (forw) { if (LIKELY(d.ymd.m < GREG_MONTHS_P_YEAR)) { d.ymd.m++; } else { d.ymd.m = 1; d.ymd.y++; } } else { if (UNLIKELY(--d.ymd.m < 1)) { d.ymd.m = GREG_MONTHS_P_YEAR; d.ymd.y--; } } /* get ultimo */ mdays = __get_mdays(d.ymd.y, d.ymd.m); if (UNLIKELY(tgt > mdays)) { tgt = mdays; } /* final assignment */ d.ymd.d = tgt; break; default: break; } break; case DT_DURBD: /* bizsis only work on bizsidurs atm */ if (dur.dv > 0) { tgt = dur.dv; forw = true; } else if (dur.dv < 0) { tgt = -dur.dv; forw = false; } else { /* user is an idiot */ break; } switch (d.typ) { unsigned int bdays; case DT_BIZDA: if ((forw && d.bizda.bd < tgt) || (!forw && d.bizda.bd > tgt)) { /* no month or year adjustment */ ; } else if (d.bizda.bd == tgt && !nextp) { /* we're ON the date already and no * next/prev date is requested */ ; } else if (forw) { if (LIKELY(d.bizda.m < GREG_MONTHS_P_YEAR)) { d.bizda.m++; } else { d.bizda.m = 1; d.bizda.y++; } } else { if (UNLIKELY(--d.bizda.m < 1)) { d.bizda.m = GREG_MONTHS_P_YEAR; d.bizda.y--; } } /* get ultimo */ bdays = __get_bdays(d.bizda.y, d.bizda.m); if (UNLIKELY(tgt > bdays)) { tgt = bdays; } /* final assignment */ d.bizda.bd = tgt; break; default: break; } break; case DT_DURYMD: switch (d.typ) { unsigned int mdays; case DT_YMD: tgt = dur.ymd.m; forw = !dt_dur_neg_p(dur); if ((forw && d.ymd.m < tgt) || (!forw && d.ymd.m > tgt)) { /* no year adjustment */ ; } else if (d.ymd.m == tgt && !nextp) { /* we're IN the month already and no * next/prev date is requested */ ; } else if (forw) { /* years don't wrap around */ d.ymd.y++; } else { /* years don't wrap around */ d.ymd.y--; } /* final assignment */ d.ymd.m = tgt; /* fixup ultimo mismatches */ mdays = __get_mdays(d.ymd.y, d.ymd.m); if (UNLIKELY(d.ymd.d > mdays)) { d.ymd.d = mdays; } break; default: break; } break; case DT_DURYMCW: { struct dt_d_s tmp; unsigned int wday; signed int diff; forw = !dt_dur_neg_p(dur); tgt = dur.ymcw.w; tmp = dt_dconv(DT_DAISY, d); wday = dt_get_wday(tmp); diff = (signed)tgt - (signed)wday; if ((forw && wday < tgt) || (!forw && wday > tgt)) { /* nothing to do */ ; } else if (wday == tgt && !nextp) { /* we're on WDAY already, do fuckall */ ; } else if (forw) { /* week wrap */ diff += 7; } else { /* week wrap */ diff -= 7; } /* final assignment */ tmp.daisy += diff; d = dt_dconv(d.typ, tmp); break; } case DT_DURWK: if (dur.dv > 0) { tgt = dur.dv; forw = true; } else if (dur.dv < 0) { tgt = -dur.dv; forw = false; } else { /* user is an idiot */ break; } switch (d.typ) { unsigned int nw; case DT_YWD: if ((forw && d.ywd.c < tgt) || (!forw && d.ywd.c > tgt)) { /* no year adjustment */ ; } else if (d.ywd.c == tgt && !nextp) { /* we're IN the week already and no * next/prev date is requested */ ; } else if (forw) { /* years don't wrap around */ d.ywd.y++; } else { /* years don't wrap around */ d.ywd.y--; } /* final assignment */ d.ywd.c = tgt; /* fixup ultimo mismatches */ nw = __get_isowk(d.ywd.y); if (UNLIKELY(d.ywd.c > nw)) { d.ywd.c = nw; } break; default: break; } break; default: break; } return d; }