9 #if defined(HAVE_SYS_TIME_H)
17 #include RUBY_EXTCONF_H
27 #define f_boolcast(x) ((x) ? Qtrue : Qfalse)
29 #define f_abs(x) rb_funcall(x, rb_intern("abs"), 0)
30 #define f_negate(x) rb_funcall(x, rb_intern("-@"), 0)
31 #define f_add(x,y) rb_funcall(x, '+', 1, y)
32 #define f_sub(x,y) rb_funcall(x, '-', 1, y)
33 #define f_mul(x,y) rb_funcall(x, '*', 1, y)
34 #define f_div(x,y) rb_funcall(x, '/', 1, y)
35 #define f_quo(x,y) rb_funcall(x, rb_intern("quo"), 1, y)
36 #define f_idiv(x,y) rb_funcall(x, rb_intern("div"), 1, y)
37 #define f_mod(x,y) rb_funcall(x, '%', 1, y)
38 #define f_remainder(x,y) rb_funcall(x, rb_intern("remainder"), 1, y)
39 #define f_expt(x,y) rb_funcall(x, rb_intern("**"), 1, y)
40 #define f_floor(x) rb_funcall(x, rb_intern("floor"), 0)
41 #define f_ceil(x) rb_funcall(x, rb_intern("ceil"), 0)
42 #define f_truncate(x) rb_funcall(x, rb_intern("truncate"), 0)
43 #define f_round(x) rb_funcall(x, rb_intern("round"), 0)
45 #define f_to_i(x) rb_funcall(x, rb_intern("to_i"), 0)
46 #define f_to_r(x) rb_funcall(x, rb_intern("to_r"), 0)
47 #define f_to_s(x) rb_funcall(x, rb_intern("to_s"), 0)
48 #define f_inspect(x) rb_funcall(x, rb_intern("inspect"), 0)
50 #define f_add3(x,y,z) f_add(f_add(x, y), z)
51 #define f_sub3(x,y,z) f_sub(f_sub(x, y), z)
124 #define f_nonzero_p(x) (!f_zero_p(x))
134 #define f_positive_p(x) (!f_negative_p(x))
136 #define f_ajd(x) rb_funcall(x, rb_intern("ajd"), 0)
137 #define f_jd(x) rb_funcall(x, rb_intern("jd"), 0)
138 #define f_year(x) rb_funcall(x, rb_intern("year"), 0)
139 #define f_mon(x) rb_funcall(x, rb_intern("mon"), 0)
140 #define f_mday(x) rb_funcall(x, rb_intern("mday"), 0)
141 #define f_wday(x) rb_funcall(x, rb_intern("wday"), 0)
142 #define f_hour(x) rb_funcall(x, rb_intern("hour"), 0)
143 #define f_min(x) rb_funcall(x, rb_intern("min"), 0)
144 #define f_sec(x) rb_funcall(x, rb_intern("sec"), 0)
147 #define NDIV(x,y) (-(-((x)+1)/(y))-1)
148 #define NMOD(x,y) ((y)-(-((x)+1)%(y))-1)
149 #define DIV(n,d) ((n)<0 ? NDIV((n),(d)) : (n)/(d))
150 #define MOD(n,d) ((n)<0 ? NMOD((n),(d)) : (n)%(d))
152 #define HAVE_JD (1 << 0)
153 #define HAVE_DF (1 << 1)
154 #define HAVE_CIVIL (1 << 2)
155 #define HAVE_TIME (1 << 3)
156 #define COMPLEX_DAT (1 << 7)
158 #define have_jd_p(x) ((x)->flags & HAVE_JD)
159 #define have_df_p(x) ((x)->flags & HAVE_DF)
160 #define have_civil_p(x) ((x)->flags & HAVE_CIVIL)
161 #define have_time_p(x) ((x)->flags & HAVE_TIME)
162 #define complex_dat_p(x) ((x)->flags & COMPLEX_DAT)
163 #define simple_dat_p(x) (!complex_dat_p(x))
165 #define ITALY 2299161
166 #define ENGLAND 2361222
167 #define JULIAN positive_inf
168 #define GREGORIAN negative_inf
169 #define DEFAULT_SG ITALY
171 #define UNIX_EPOCH_IN_CJD INT2FIX(2440588)
173 #define MINUTE_IN_SECONDS 60
174 #define HOUR_IN_SECONDS 3600
175 #define DAY_IN_SECONDS 86400
176 #define SECOND_IN_MILLISECONDS 1000
177 #define SECOND_IN_NANOSECONDS 1000000000
179 #define JC_PERIOD0 1461
180 #define GC_PERIOD0 146097
181 #define CM_PERIOD0 71149239
182 #define CM_PERIOD (0xfffffff / CM_PERIOD0 * CM_PERIOD0)
183 #define CM_PERIOD_JCY (CM_PERIOD / JC_PERIOD0 * 4)
184 #define CM_PERIOD_GCY (CM_PERIOD / GC_PERIOD0 * 400)
186 #define REFORM_BEGIN_YEAR 1582
187 #define REFORM_END_YEAR 1930
188 #define REFORM_BEGIN_JD 2298874
189 #define REFORM_END_JD 2426355
199 #define MIN_SHIFT SEC_WIDTH
200 #define HOUR_SHIFT (MIN_WIDTH + SEC_WIDTH)
201 #define MDAY_SHIFT (HOUR_WIDTH + MIN_WIDTH + SEC_WIDTH)
202 #define MON_SHIFT (MDAY_WIDTH + HOUR_WIDTH + MIN_WIDTH + SEC_WIDTH)
204 #define PK_MASK(x) ((1 << (x)) - 1)
206 #define EX_SEC(x) (((x) >> SEC_SHIFT) & PK_MASK(SEC_WIDTH))
207 #define EX_MIN(x) (((x) >> MIN_SHIFT) & PK_MASK(MIN_WIDTH))
208 #define EX_HOUR(x) (((x) >> HOUR_SHIFT) & PK_MASK(HOUR_WIDTH))
209 #define EX_MDAY(x) (((x) >> MDAY_SHIFT) & PK_MASK(MDAY_WIDTH))
210 #define EX_MON(x) (((x) >> MON_SHIFT) & PK_MASK(MON_WIDTH))
212 #define PACK5(m,d,h,min,s) \
213 (((m) << MON_SHIFT) | ((d) << MDAY_SHIFT) |\
214 ((h) << HOUR_SHIFT) | ((min) << MIN_SHIFT) | ((s) << SEC_SHIFT))
217 (((m) << MON_SHIFT) | ((d) << MDAY_SHIFT))
224 #if defined(FLT_RADIX) && defined(FLT_MANT_DIG) && FLT_RADIX == 2 && FLT_MANT_DIG > 22
225 #define date_sg_t float
227 #define date_sg_t double
288 union DateData *dat;\
289 Data_Get_Struct(x, union DateData, dat);
292 union DateData *adat;\
293 Data_Get_Struct(x, union DateData, adat);
296 union DateData *bdat;\
297 Data_Get_Struct(x, union DateData, bdat);
300 union DateData *adat, *bdat;\
301 Data_Get_Struct(x, union DateData, adat);\
302 Data_Get_Struct(y, union DateData, bdat);
316 #define set_to_simple(x, _nth, _jd ,_sg, _year, _mon, _mday, _flags) \
318 (x)->nth = canon(_nth);\
320 (x)->sg = (date_sg_t)(_sg);\
324 (x)->flags = _flags;\
327 #define set_to_simple(x, _nth, _jd ,_sg, _year, _mon, _mday, _flags) \
329 (x)->nth = canon(_nth);\
331 (x)->sg = (date_sg_t)(_sg);\
333 (x)->pc = PACK2(_mon, _mday);\
334 (x)->flags = _flags;\
339 #define set_to_complex(x, _nth, _jd ,_df, _sf, _of, _sg,\
340 _year, _mon, _mday, _hour, _min, _sec, _flags) \
342 (x)->nth = canon(_nth);\
345 (x)->sf = canon(_sf);\
347 (x)->sg = (date_sg_t)(_sg);\
354 (x)->flags = _flags;\
357 #define set_to_complex(x, _nth, _jd ,_df, _sf, _of, _sg,\
358 _year, _mon, _mday, _hour, _min, _sec, _flags) \
360 (x)->nth = canon(_nth);\
363 (x)->sf = canon(_sf);\
365 (x)->sg = (date_sg_t)(_sg);\
367 (x)->pc = PACK5(_mon, _mday, _hour, _min, _sec);\
368 (x)->flags = _flags;\
373 #define copy_simple_to_complex(x, y) \
375 (x)->nth = (y)->nth;\
378 (x)->sf = INT2FIX(0);\
380 (x)->sg = (date_sg_t)((y)->sg);\
381 (x)->year = (y)->year;\
382 (x)->mon = (y)->mon;\
383 (x)->mday = (y)->mday;\
387 (x)->flags = (y)->flags;\
390 #define copy_simple_to_complex(x, y) \
392 (x)->nth = (y)->nth;\
395 (x)->sf = INT2FIX(0);\
397 (x)->sg = (date_sg_t)((y)->sg);\
398 (x)->year = (y)->year;\
399 (x)->pc = PACK5(EX_MON((y)->pc), EX_MDAY((y)->pc), 0, 0, 0);\
400 (x)->flags = (y)->flags;\
405 #define copy_complex_to_simple(x, y) \
407 (x)->nth = (y)->nth;\
409 (x)->sg = (date_sg_t)((y)->sg);\
410 (x)->year = (y)->year;\
411 (x)->mon = (y)->mon;\
412 (x)->mday = (y)->mday;\
413 (x)->flags = (y)->flags;\
416 #define copy_complex_to_simple(x, y) \
418 (x)->nth = (y)->nth;\
420 (x)->sg = (date_sg_t)((y)->sg);\
421 (x)->year = (y)->year;\
422 (x)->pc = PACK2(EX_MON((y)->pc), EX_MDAY((y)->pc));\
423 (x)->flags = (y)->flags;\
430 int *,
int *,
int *,
int *);
437 for (d = 1; d < 31; d++)
448 for (i = 0; i < 30; i++)
456 c_find_fdom(
int y,
int m,
double sg,
int *rjd,
int *ns)
460 for (d = 1; d < 31; d++)
472 for (i = 0; i < 30; i++)
487 a = floor(y / 100.0);
488 b = 2 - a + floor(a / 4.0);
489 jd = floor(365.25 * (y + 4716)) +
490 floor(30.6001 * (m + 1)) +
505 double x, a, b,
c, d, e, y, m, dom;
510 x = floor((jd - 1867216.25) / 36524.25);
511 a = jd + 1 + x - floor(x / 4.0);
514 c = floor((b - 122.1) / 365.25);
515 d = floor(365.25 * c);
516 e = floor((b - d) / 30.6001);
517 dom = b - d - floor(30.6001 * e);
539 *ns = (*rjd <
sg) ? 0 : 1;
545 int rm2, rd2, rjd, ns;
549 *rd = (jd - rjd) + 1;
560 (rjd2 -
MOD((rjd2 - 1) + 1, 7)) +
563 *ns = (*rjd <
sg) ? 0 : 1;
569 int ry2, rm2, rd2, a, rjd2, ns2;
580 *rw = 1 +
DIV(jd - rjd2, 7);
581 *rd =
MOD(jd + 1, 7);
593 *rjd = (rjd2 -
MOD(((rjd2 - f) + 1), 7) - 7) + 7 * w + d;
594 *ns = (*rjd <
sg) ? 0 : 1;
600 int rm, rd2, rjd, ns, j;
605 j = jd - (rjd -
MOD((rjd - f) + 1, 7)) + 7;
606 *rw = (int)
DIV(j, 7);
607 *rd = (int)
MOD(j, 7);
612 c_nth_kday_to_jd(
int y,
int m,
int n,
int k,
double sg,
int *rjd,
int *ns)
617 c_find_fdom(y, m, sg, &rjd2, &ns2);
624 *rjd = (rjd2 -
MOD((rjd2 - k) + 1, 7)) + 7 * n;
625 *ns = (*rjd <
sg) ? 0 : 1;
632 return MOD(jd + 1, 7);
637 c_jd_to_nth_kday(
int jd,
double sg,
int *ry,
int *rm,
int *rn,
int *rk)
642 c_find_fdom(*ry, *rm, sg, &rjd, &ns2);
643 *rn =
DIV(jd - rjd, 7) + 1;
650 int *rd,
int *rjd,
int *ns)
666 if (ry2 != y || rd2 != d)
672 { 0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 },
673 { 0, 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 }
679 return MOD(y, 4) == 0;
685 return (
MOD(y, 4) == 0 && y % 100 != 0) ||
MOD(y, 400) == 0;
691 assert(m >= 1 && m <= 12);
698 assert(m >= 1 && m <= 12);
714 if (d < 1 || d > last)
733 if (d < 1 || d > last)
742 int *rm,
int *rd,
int *rjd,
int *ns)
752 if (ry != y || *rm != m)
758 if (ry != y || *rm != m || *rd != d)
765 int *rw,
int *rd,
int *rjd,
int *ns)
767 int ns2, ry2, rw2, rd2;
782 if (y != ry2 || w != *rw || d != *rd)
789 int *rw,
int *rd,
int *rjd,
int *ns)
791 int ns2, ry2, rw2, rd2;
806 if (y != ry2 || w != *rw || d != *rd)
813 c_valid_nth_kday_p(
int y,
int m,
int n,
int k,
double sg,
814 int *rm,
int *rn,
int *rk,
int *rjd,
int *ns)
816 int ns2, ry2, rm2, rn2, rk2;
827 c_nth_kday_to_jd(ny, nm, 1, k, sg, &rjd2, &ns2);
828 c_jd_to_nth_kday(rjd2 + n * 7, sg, &ry2, &rm2, &rn2, &rk2);
829 if (ry2 != y || rm2 != m)
833 c_nth_kday_to_jd(y, m, n, k, sg, rjd, ns);
834 c_jd_to_nth_kday(*rjd, sg, &ry2, rm, rn, rk);
835 if (y != ry2 || m != *rm || n != *rn || k != *rk)
853 return !(h < 0 || h > 24 ||
854 min < 0 || min > 59 ||
856 (h == 24 && (min > 0 || s > 0)));
1077 inline static double
1089 inline static double
1101 inline static double
1110 #define canonicalize_jd(_nth, _jd) \
1113 _nth = f_sub(_nth, INT2FIX(1));\
1116 if (_jd >= CM_PERIOD) {\
1117 _nth = f_add(_nth, INT2FIX(1));\
1203 int r, m, d, h, min, s;
1266 int jd, y, m, d, h, min, s;
1311 period = (style < 0) ?
1321 inth =
DIV(it, ((
long)period));
1324 it =
MOD(it, ((
long)period));
1325 *ry = (int)it - 4712;
1343 period = (style < 0) ?
1378 inline static double
1508 m_local_df_in_day(
union DateData *x)
1555 #define HALF_DAYS_IN_SECONDS (DAY_IN_SECONDS / 2)
1635 inline static double
1679 if (
isinf(sg) && sg > 0)
1690 if (
isinf(sg) && sg < 0)
1769 { 0, 0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334 },
1770 { 0, 0, 31, 60, 91, 121, 152, 182, 213, 244, 274, 305, 335 }
1776 assert(m >= 1 && m <= 12);
1783 assert(m >= 1 && m <= 12);
1927 #define decode_offset(of,s,h,m)\
1930 s = (of < 0) ? '-' : '+';\
1931 a = (of < 0) ? -of : of;\
1932 h = a / HOUR_IN_SECONDS;\
1933 m = a % HOUR_IN_SECONDS / MINUTE_IN_SECONDS;\
1979 civil_to_jd(
VALUE y,
int m,
int d,
double sg,
2005 jd_to_civil(
VALUE jd,
double sg,
2006 VALUE *nth,
int *rjd,
2007 int *ry,
int *rm,
int *rd)
2014 ordinal_to_jd(
VALUE y,
int d,
double sg,
2015 VALUE *nth,
int *ry,
2040 jd_to_ordinal(
VALUE jd,
double sg,
2041 VALUE *nth,
int *rjd,
2049 commercial_to_jd(
VALUE y,
int w,
int d,
double sg,
2050 VALUE *nth,
int *ry,
2075 jd_to_commercial(
VALUE jd,
double sg,
2076 VALUE *nth,
int *rjd,
2077 int *ry,
int *rw,
int *rd)
2084 weeknum_to_jd(
VALUE y,
int w,
int d,
int f,
double sg,
2085 VALUE *nth,
int *ry,
2110 jd_to_weeknum(
VALUE jd,
int f,
double sg,
2111 VALUE *nth,
int *rjd,
2112 int *ry,
int *rw,
int *rd)
2119 nth_kday_to_jd(
VALUE y,
int m,
int n,
int k,
double sg,
2120 VALUE *nth,
int *ry,
2129 c_nth_kday_to_jd(
FIX2INT(y), m, n, k, sg, &jd, ns);
2140 c_nth_kday_to_jd(*ry, m, n, k, style, rjd, ns);
2145 jd_to_nth_kday(
VALUE jd,
double sg,
2146 VALUE *nth,
int *rjd,
2147 int *ry,
int *rm,
int *rn,
int *rk)
2150 c_jd_to_nth_kday(*rjd, sg, ry, rm, rn, rk);
2156 VALUE *nth,
int *ry,
2186 VALUE *nth,
int *ry,
2195 VALUE *nth,
int *ry,
2196 int *rm,
int *rd,
int *rjd,
2231 VALUE *nth,
int *ry,
2232 int *rw,
int *rd,
int *rjd,
2261 VALUE *nth,
int *ry,
2262 int *rw,
int *rd,
int *rjd,
2291 valid_nth_kday_p(
VALUE y,
int m,
int n,
int k,
double sg,
2292 VALUE *nth,
int *ry,
2293 int *rm,
int *rn,
int *rk,
int *rjd,
2302 r = c_valid_nth_kday_p(
FIX2INT(y), m, n, k, sg, rm, rn, rk, &jd, ns);
2315 r = c_valid_nth_kday_p(*ry, m, n, k, style, rm, rn, rk, rjd, ns);
2326 switch (
TYPE(vof)) {
2332 if (n != -1 && n != 0 && n != 1)
2344 *rof = (int)
round(n);
2353 #ifdef CANONICALIZATION_FOR_MATHN
2365 #ifdef CANONICALIZATION_FOR_MATHN
2413 #define valid_sg(sg) \
2415 if (!c_valid_start_p(sg)) {\
2417 rb_warning("invalid start is ignored");\
2481 int m, d, ry, rm, rd;
2516 date_s__valid_civil_p(
int argc,
VALUE *argv,
VALUE klass)
2518 VALUE vy, vm, vd, vsg;
2550 VALUE vy, vm, vd, vsg;
2599 date_s__valid_ordinal_p(
int argc,
VALUE *argv,
VALUE klass)
2652 int w, d, ry, rw, rd;
2680 date_s__valid_commercial_p(
int argc,
VALUE *argv,
VALUE klass)
2682 VALUE vy, vw, vd, vsg;
2713 VALUE vy, vw, vd, vsg;
2733 valid_weeknum_sub(
int argc,
VALUE *argv,
VALUE klass,
int need_jd)
2736 int w, d, f, ry, rw, rd;
2764 date_s__valid_weeknum_p(
int argc,
VALUE *argv,
VALUE klass)
2766 VALUE vy, vw, vd, vf, vsg;
2769 rb_scan_args(argc, argv,
"41", &vy, &vw, &vd, &vf, &vsg);
2780 return valid_weeknum_sub(5, argv2, klass, 1);
2784 date_s_valid_weeknum_p(
int argc,
VALUE *argv,
VALUE klass)
2786 VALUE vy, vw, vd, vf, vsg;
2789 rb_scan_args(argc, argv,
"41", &vy, &vw, &vd, &vf, &vsg);
2800 if (
NIL_P(valid_weeknum_sub(5, argv2, klass, 0)))
2806 valid_nth_kday_sub(
int argc,
VALUE *argv,
VALUE klass,
int need_jd)
2809 int m, n, k, ry, rm, rn, rk;
2822 if (!valid_nth_kday_p(y, m, n, k, sg,
2824 &rm, &rn, &rk, &rjd,
2835 date_s__valid_nth_kday_p(
int argc,
VALUE *argv,
VALUE klass)
2837 VALUE vy, vm, vn, vk, vsg;
2840 rb_scan_args(argc, argv,
"41", &vy, &vm, &vn, &vk, &vsg);
2851 return valid_nth_kday_sub(5, argv2, klass, 1);
2855 date_s_valid_nth_kday_p(
int argc,
VALUE *argv,
VALUE klass)
2857 VALUE vy, vm, vn, vk, vsg;
2860 rb_scan_args(argc, argv,
"41", &vy, &vm, &vn, &vk, &vsg);
2871 if (
NIL_P(valid_nth_kday_sub(5, argv2, klass, 0)))
2940 int y,
int m,
int d,
2960 int y,
int m,
int d,
2961 int h,
int min,
int s,
3009 int *rof,
double *rsg)
3047 date_s_new_bang(
int argc,
VALUE *argv,
VALUE klass)
3065 &nth, &jd, &df, &sf, &rof, &rsg);
3095 return round(d) == d;
3132 #define jd_trunc d_trunc
3133 #define k_trunc d_trunc
3186 #define num2num_with_frac(s,n) \
3188 s = s##_trunc(v##s, &fr);\
3189 if (f_nonzero_p(fr)) {\
3191 rb_raise(rb_eArgError, "invalid fraction");\
3196 #define num2int_with_frac(s,n) \
3198 s = NUM2INT(s##_trunc(v##s, &fr));\
3199 if (f_nonzero_p(fr)) {\
3201 rb_raise(rb_eArgError, "invalid fraction");\
3206 #define canon24oc() \
3210 fr2 = f_add(fr2, INT2FIX(1));\
3214 #define add_frac() \
3216 if (f_nonzero_p(fr2))\
3217 ret = d_lite_plus(ret, fr2);\
3220 #define val2sg(vsg,dsg) \
3222 dsg = NUM2DBL(vsg);\
3223 if (!c_valid_start_p(dsg)) {\
3225 rb_warning("invalid start is ignored");\
3247 VALUE vjd, vsg,
jd, fr, fr2, ret;
3297 VALUE vy, vd, vsg, y, fr, fr2, ret;
3319 int ry, rd, rjd, ns;
3365 VALUE vy, vm, vd, vsg, y, fr, fr2, ret;
3405 int ry, rm, rd, rjd, ns;
3442 VALUE vy, vw, vd, vsg, y, fr, fr2, ret;
3467 int ry, rw, rd, rjd, ns;
3487 date_s_weeknum(
int argc,
VALUE *argv,
VALUE klass)
3489 VALUE vy, vw, vd, vf, vsg, y, fr, fr2, ret;
3493 rb_scan_args(argc, argv,
"05", &vy, &vw, &vd, &vf, &vsg);
3517 int ry, rw, rd, rjd, ns;
3536 date_s_nth_kday(
int argc,
VALUE *argv,
VALUE klass)
3538 VALUE vy, vm, vn, vk, vsg, y, fr, fr2, ret;
3542 rb_scan_args(argc, argv,
"05", &vy, &vm, &vn, &vk, &vsg);
3566 int ry, rm, rn, rk, rjd, ns;
3568 if (!valid_nth_kday_p(y, m, n, k, sg,
3570 &rm, &rn, &rk, &rjd,
3585 #if !defined(HAVE_GMTIME_R)
3589 auto struct tm *tmp = gmtime(t);
3598 auto struct tm *tmp = localtime(t);
3618 VALUE vsg, nth, ret;
3637 y = tm.tm_year + 1900;
3655 #define set_hash0(k,v) rb_hash_aset(hash, k, v)
3656 #define ref_hash0(k) rb_hash_aref(hash, k)
3657 #define del_hash0(k) rb_hash_delete(hash, k)
3659 #define set_hash(k,v) rb_hash_aset(hash, ID2SYM(rb_intern(k)), v)
3660 #define ref_hash(k) rb_hash_aref(hash, ID2SYM(rb_intern(k)))
3661 #define del_hash(k) rb_hash_delete(hash, ID2SYM(rb_intern(k)))
3669 if (!
NIL_P(seconds)) {
3670 VALUE d, h, min, s, fr;
3695 #define sym(x) ID2SYM(rb_intern(x))
3802 int i, eno = 0, idx = 0;
3813 for (j = 0; j < RARRAY_LENINT(a); j++)
3835 if (k ==
sym(
"ordinal")) {
3844 else if (k ==
sym(
"civil")) {
3861 else if (k ==
sym(
"commercial")) {
3878 else if (k ==
sym(
"wday")) {
3885 else if (k ==
sym(
"wnum0")) {
3902 else if (k ==
sym(
"wnum1")) {
3921 if (g && k ==
sym(
"time")) {
3952 int ry, rd, rjd, ns;
3967 int ry, rm, rd, rjd, ns;
3982 int ry, rw, rd, rjd, ns;
3997 int ry, rw, rd, rjd, ns;
4033 VALUE year, mon, mday;
4045 VALUE year, week, wday;
4065 VALUE year, week, wday;
4085 VALUE year, week, wday;
4148 const char *fmt,
size_t flen,
VALUE hash);
4152 const char *default_fmt)
4155 const char *str, *fmt;
4163 "string should have ASCII compatible encoding");
4168 flen =
strlen(default_fmt);
4174 "format should have ASCII compatible encoding");
4275 "string should have ASCII compatible encoding");
4332 VALUE str, comp, sg;
4520 str =
rb_str_new2(
"Mon, 1 Jan -4712 00:00:00 +0000");
4562 str =
rb_str_new2(
"Mon, 01 Jan -4712 00:00:00 GMT");
4661 #define val2off(vof,iof) \
4663 if (!offset_to_sec(vof, &iof)) {\
4665 rb_warning("invalid offset is ignored");\
4671 d_lite_initialize(
int argc,
VALUE *argv,
VALUE self)
4673 VALUE jd, vjd, vdf, sf, vsf, vof, vsg;
4680 rb_scan_args(argc, argv,
"05", &vjd, &vdf, &vsf, &vof, &vsg);
4719 "cannot load complex into simple");
4747 "cannot load complex into simple");
4758 d_lite_fill(
VALUE self)
4988 d_lite_wnum0(
VALUE self)
4995 d_lite_wnum1(
VALUE self)
5265 int rjd, ns, ry, rm, rd;
5486 switch (
TYPE(other)) {
5503 jd =
m_jd(dat) + (int)t;
5517 dat->c.df, dat->c.sf,
5518 dat->c.of, dat->c.sg,
5556 jd =
m_jd(dat) + jd;
5575 dat->c.df, dat->c.sf,
5576 dat->c.of, dat->c.sg,
5649 df =
m_df(dat) + df;
5663 jd =
m_jd(dat) + jd;
5696 #ifdef CANONICALIZATION_FOR_MATHN
5752 df =
m_df(dat) + df;
5766 jd =
m_jd(dat) + jd;
5872 switch (
TYPE(other)) {
5948 VALUE t, y, nth, rjd2;
5975 &rm, &rd, &rjd, &ns))
6085 VALUE limit, step, date;
6192 a_nth =
m_nth(adat);
6193 b_nth =
m_nth(bdat);
6206 else if (
f_lt_p(a_sf, b_sf)) {
6213 else if (a_df < b_df) {
6220 else if (a_jd < b_jd) {
6227 else if (
f_lt_p(a_nth, b_nth)) {
6263 return cmp_dd(
self, other);
6271 a_nth =
m_nth(adat);
6272 b_nth =
m_nth(bdat);
6279 else if (a_jd < b_jd) {
6286 else if (
f_lt_p(a_nth, b_nth)) {
6343 a_nth =
m_nth(adat);
6344 b_nth =
m_nth(bdat);
6401 mk_inspect_flags(
union DateData *x)
6413 mk_inspect_raw(
union DateData *x,
const char *klass)
6423 "(%sth,%dj),+0s,%.0fj; "
6425 klass ? klass :
"?",
6428 x->
s.
year, x->
s.mon, x->
s.mday,
6436 VALUE nth, sf, flags;
6444 "(%sth,%dj,%ds,%sn),%+ds,%.0fj; "
6445 "%dy%dm%dd %dh%dm%ds; %s>",
6446 klass ? klass :
"?",
6451 x->
c.
year, x->
c.mon, x->
c.mday,
6452 x->
c.hour, x->
c.min, x->
c.sec,
6464 d_lite_inspect_raw(
VALUE self)
6480 "#<%s: %s ((%sj,%ds,%sn),%+ds,%.0fj)>",
6481 klass ? klass :
"?",
6513 size_t date_strftime(
char *s,
size_t maxsize,
const char *format,
6516 #define SMALLBUF 100
6521 size_t size, len, flen;
6530 if (len != 0 || (**buf ==
'\0' &&
errno != ERANGE))
return len;
6531 for (size=1024; ; size*=2) {
6544 if (size >= 1024 * flen) {
6568 #define MILLISECOND_IN_NANOSECONDS 1000000
6599 (int (*)(
void *))
m_mon,
6608 (int (*)(
void *))
m_min,
6609 (int (*)(
void *))
m_sec,
6621 tmx->
dat = (
void *)dat;
6627 const char *default_fmt,
6645 "format should have ASCII compatible encoding");
6650 (*func)(
self, &tmx);
6651 if (memchr(fmt,
'\0', len)) {
6653 const char *p = fmt, *pe = fmt + len;
6660 if (buf != buffer) {
6664 for (fmt = p; p < pe && !*p; ++p);
6675 if (buf != buffer)
xfree(buf);
6873 (*func)(
self, &tmx);
6876 if (buf != buffer)
xfree(buf);
6995 d_lite_marshal_dump_old(
VALUE self)
7006 if (
FL_TEST(
self, FL_EXIVAR)) {
7055 VALUE ajd, of, sg, nth, sf;
7074 &nth, &jd, &df, &sf, &rof, &rsg);
7081 "cannot load complex into simple");
7106 "cannot load complex into simple");
7155 VALUE vjd, vh, vmin, vs, vof, vsg, jd, fr, fr2, ret;
7159 rb_scan_args(argc, argv,
"06", &vjd, &vh, &vmin, &vs, &vof, &vsg);
7185 int rh, rmin, rs, rjd, rjd2;
7223 VALUE vy, vd, vh, vmin, vs, vof, vsg, y, fr, fr2, ret;
7224 int d, h, min, s, rof;
7227 rb_scan_args(argc, argv,
"07", &vy, &vd, &vh, &vmin, &vs, &vof, &vsg);
7256 int ry, rd, rh, rmin, rs, rjd, rjd2, ns;
7299 VALUE vy, vm, vd, vh, vmin, vs, vof, vsg, y, fr, fr2, ret;
7300 int m, d, h, min, s, rof;
7303 rb_scan_args(argc, argv,
"08", &vy, &vm, &vd, &vh, &vmin, &vs, &vof, &vsg);
7335 int ry, rm, rd, rh, rmin, rs;
7355 int ry, rm, rd, rh, rmin, rs, rjd, rjd2, ns;
7396 VALUE vy, vw, vd, vh, vmin, vs, vof, vsg, y, fr, fr2, ret;
7397 int w, d, h, min, s, rof;
7400 rb_scan_args(argc, argv,
"08", &vy, &vw, &vd, &vh, &vmin, &vs, &vof, &vsg);
7432 int ry, rw, rd, rh, rmin, rs, rjd, rjd2, ns;
7461 datetime_s_weeknum(
int argc,
VALUE *argv,
VALUE klass)
7463 VALUE vy, vw, vd, vf, vh, vmin, vs, vof, vsg, y, fr, fr2, ret;
7464 int w, d, f, h, min, s, rof;
7468 &vh, &vmin, &vs, &vof, &vsg);
7503 int ry, rw, rd, rh, rmin, rs, rjd, rjd2, ns;
7530 datetime_s_nth_kday(
int argc,
VALUE *argv,
VALUE klass)
7532 VALUE vy, vm, vn, vk, vh, vmin, vs, vof, vsg, y, fr, fr2, ret;
7533 int m, n, k, h, min, s, rof;
7537 &vh, &vmin, &vs, &vof, &vsg);
7572 int ry, rm, rn, rk, rh, rmin, rs, rjd, rjd2, ns;
7574 if (!valid_nth_kday_p(y, m, n, k, sg,
7576 &rm, &rn, &rk, &rjd,
7610 VALUE vsg, nth, ret;
7612 #ifdef HAVE_CLOCK_GETTIME
7620 int y, ry, m, d, h, min, s;
7629 #ifdef HAVE_CLOCK_GETTIME
7642 y = tm.tm_year + 1900;
7650 #ifdef HAVE_STRUCT_TM_TM_GMTOFF
7652 #elif defined(HAVE_VAR_TIMEZONE)
7653 #ifdef HAVE_VAR_ALTZONE
7654 of = (long)-((tm.tm_isdst > 0) ? altzone :
timezone);
7662 of += (long)difftime(sec2, sec);
7665 #elif defined(HAVE_TIMEGM)
7670 of = (long)difftime(sec2, sec);
7679 tm2.tm_isdst = tm.tm_isdst;
7680 sec2 = mktime(&tm2);
7681 of = (long)difftime(sec, sec2);
7684 #ifdef HAVE_CLOCK_GETTIME
7887 VALUE str, comp, sg;
8024 str =
rb_str_new2(
"Mon, 1 Jan -4712 00:00:00 +0000");
8054 str =
rb_str_new2(
"Mon, 01 Jan -4712 00:00:00 GMT");
8292 "%Y-%m-%dT%H:%M:%S%:z",
set_tmx);
8390 #define f_getlocal(x) rb_funcall(x, rb_intern("getlocal"), 0)
8391 #define f_subsec(x) rb_funcall(x, rb_intern("subsec"), 0)
8392 #define f_utc_offset(x) rb_funcall(x, rb_intern("utc_offset"), 0)
8393 #define f_local3(x,y,m,d) rb_funcall(x, rb_intern("local"), 3, y, m, d)
8394 #define f_utc6(x,y,m,d,h,min,s) rb_funcall(x, rb_intern("utc"), 6,\
8448 VALUE y, sf, nth, ret;
8449 int ry, m, d, h, min, s, of;
8623 #define MIN_YEAR -4713
8624 #define MAX_YEAR 1000000
8626 #define MAX_JD 366963925
8629 test_civil(
int from,
int to,
double sg)
8633 fprintf(stderr,
"test_civil: %d...%d (%d) - %.0f\n",
8634 from, to, to - from, sg);
8635 for (j = from; j <= to; j++) {
8636 int y, m, d, rj, ns;
8641 fprintf(stderr,
"%d != %d\n", j, rj);
8649 date_s_test_civil(
VALUE klass)
8651 if (!test_civil(MIN_JD, MIN_JD + 366,
GREGORIAN))
8653 if (!test_civil(2305814, 2598007,
GREGORIAN))
8655 if (!test_civil(MAX_JD - 366, MAX_JD,
GREGORIAN))
8658 if (!test_civil(MIN_JD, MIN_JD + 366,
ITALY))
8660 if (!test_civil(2305814, 2598007,
ITALY))
8662 if (!test_civil(MAX_JD - 366, MAX_JD,
ITALY))
8669 test_ordinal(
int from,
int to,
double sg)
8673 fprintf(stderr,
"test_ordinal: %d...%d (%d) - %.0f\n",
8674 from, to, to - from, sg);
8675 for (j = from; j <= to; j++) {
8681 fprintf(stderr,
"%d != %d\n", j, rj);
8689 date_s_test_ordinal(
VALUE klass)
8691 if (!test_ordinal(MIN_JD, MIN_JD + 366,
GREGORIAN))
8693 if (!test_ordinal(2305814, 2598007,
GREGORIAN))
8695 if (!test_ordinal(MAX_JD - 366, MAX_JD,
GREGORIAN))
8698 if (!test_ordinal(MIN_JD, MIN_JD + 366,
ITALY))
8700 if (!test_ordinal(2305814, 2598007,
ITALY))
8702 if (!test_ordinal(MAX_JD - 366, MAX_JD,
ITALY))
8709 test_commercial(
int from,
int to,
double sg)
8713 fprintf(stderr,
"test_commercial: %d...%d (%d) - %.0f\n",
8714 from, to, to - from, sg);
8715 for (j = from; j <= to; j++) {
8716 int y, w, d, rj, ns;
8721 fprintf(stderr,
"%d != %d\n", j, rj);
8729 date_s_test_commercial(
VALUE klass)
8731 if (!test_commercial(MIN_JD, MIN_JD + 366,
GREGORIAN))
8733 if (!test_commercial(2305814, 2598007,
GREGORIAN))
8735 if (!test_commercial(MAX_JD - 366, MAX_JD,
GREGORIAN))
8738 if (!test_commercial(MIN_JD, MIN_JD + 366,
ITALY))
8740 if (!test_commercial(2305814, 2598007,
ITALY))
8742 if (!test_commercial(MAX_JD - 366, MAX_JD,
ITALY))
8749 test_weeknum(
int from,
int to,
int f,
double sg)
8753 fprintf(stderr,
"test_weeknum: %d...%d (%d) - %.0f\n",
8754 from, to, to - from, sg);
8755 for (j = from; j <= to; j++) {
8756 int y, w, d, rj, ns;
8761 fprintf(stderr,
"%d != %d\n", j, rj);
8769 date_s_test_weeknum(
VALUE klass)
8773 for (f = 0; f <= 1; f++) {
8774 if (!test_weeknum(MIN_JD, MIN_JD + 366, f,
GREGORIAN))
8776 if (!test_weeknum(2305814, 2598007, f,
GREGORIAN))
8778 if (!test_weeknum(MAX_JD - 366, MAX_JD, f,
GREGORIAN))
8781 if (!test_weeknum(MIN_JD, MIN_JD + 366, f,
ITALY))
8783 if (!test_weeknum(2305814, 2598007, f,
ITALY))
8785 if (!test_weeknum(MAX_JD - 366, MAX_JD, f,
ITALY))
8793 test_nth_kday(
int from,
int to,
double sg)
8797 fprintf(stderr,
"test_nth_kday: %d...%d (%d) - %.0f\n",
8798 from, to, to - from, sg);
8799 for (j = from; j <= to; j++) {
8800 int y, m, n, k, rj, ns;
8802 c_jd_to_nth_kday(j, sg, &y, &m, &n, &k);
8803 c_nth_kday_to_jd(y, m, n, k, sg, &rj, &ns);
8805 fprintf(stderr,
"%d != %d\n", j, rj);
8813 date_s_test_nth_kday(
VALUE klass)
8815 if (!test_nth_kday(MIN_JD, MIN_JD + 366,
GREGORIAN))
8817 if (!test_nth_kday(2305814, 2598007,
GREGORIAN))
8819 if (!test_nth_kday(MAX_JD - 366, MAX_JD,
GREGORIAN))
8822 if (!test_nth_kday(MIN_JD, MIN_JD + 366,
ITALY))
8824 if (!test_nth_kday(2305814, 2598007,
ITALY))
8826 if (!test_nth_kday(MAX_JD - 366, MAX_JD,
ITALY))
8833 test_unit_v2v(
VALUE i,
8847 if (!test_unit_v2v(
INT2FIX(0), conv1, conv2))
8849 if (!test_unit_v2v(
INT2FIX(1), conv1, conv2))
8851 if (!test_unit_v2v(
INT2FIX(2), conv1, conv2))
8853 if (!test_unit_v2v(
INT2FIX(3), conv1, conv2))
8855 if (!test_unit_v2v(
INT2FIX(11), conv1, conv2))
8857 if (!test_unit_v2v(
INT2FIX(65535), conv1, conv2))
8859 if (!test_unit_v2v(
INT2FIX(1073741823), conv1, conv2))
8861 if (!test_unit_v2v(
INT2NUM(1073741824), conv1, conv2))
8878 if (!test_unit_v2v_iter2(conv1, conv2))
8880 if (!test_unit_v2v_iter2(conv2, conv1))
8886 date_s_test_unit_conv(
VALUE klass)
8890 if (!test_unit_v2v_iter(ms_to_sec,
sec_to_ms))
8892 if (!test_unit_v2v_iter(
ns_to_day, day_to_ns))
8900 date_s_test_all(
VALUE klass)
8902 if (date_s_test_civil(klass) == Qfalse)
8904 if (date_s_test_ordinal(klass) == Qfalse)
8906 if (date_s_test_commercial(klass) == Qfalse)
8908 if (date_s_test_weeknum(klass) == Qfalse)
8910 if (date_s_test_nth_kday(klass) == Qfalse)
8912 if (date_s_test_unit_conv(klass) == Qfalse)
8920 "January",
"February",
"March",
8921 "April",
"May",
"June",
8922 "July",
"August",
"September",
8923 "October",
"November",
"December"
8928 "Jan",
"Feb",
"Mar",
"Apr",
8929 "May",
"Jun",
"Jul",
"Aug",
8930 "Sep",
"Oct",
"Nov",
"Dec"
8934 "Sunday",
"Monday",
"Tuesday",
"Wednesday",
8935 "Thursday",
"Friday",
"Saturday"
8939 "Sun",
"Mon",
"Tue",
"Wed",
8950 for (i = 0; i < len; i++) {
8969 #define rb_intern(str) rb_intern_const(str)
8971 assert(fprintf(stderr,
"assert() is now active\n"));
8980 #if (LONG_MAX / DAY_IN_SECONDS) > SECOND_IN_NANOSECONDS
8983 #elif defined HAVE_LONG_LONG
8985 SECOND_IN_NANOSECONDS);
8988 INT2FIX(SECOND_IN_NANOSECONDS));
9245 #define de_define_private_method rb_define_private_method
9247 date_s__valid_jd_p, -1);
9248 de_define_private_method(
CLASS_OF(
cDate),
"_valid_ordinal?",
9249 date_s__valid_ordinal_p, -1);
9251 date_s__valid_civil_p, -1);
9253 date_s__valid_civil_p, -1);
9254 de_define_private_method(
CLASS_OF(
cDate),
"_valid_commercial?",
9255 date_s__valid_commercial_p, -1);
9256 de_define_private_method(
CLASS_OF(
cDate),
"_valid_weeknum?",
9257 date_s__valid_weeknum_p, -1);
9258 de_define_private_method(
CLASS_OF(
cDate),
"_valid_nth_kday?",
9259 date_s__valid_nth_kday_p, -1);
9272 date_s_valid_weeknum_p, -1);
9273 de_define_private_method(
CLASS_OF(
cDate),
"valid_nth_kday?",
9274 date_s_valid_nth_kday_p, -1);
9276 date_s_zone_to_diff, 1);
9286 #define de_define_singleton_method rb_define_singleton_method
9287 #define de_define_alias rb_define_alias
9288 de_define_singleton_method(
cDate,
"new!", date_s_new_bang, -1);
9299 de_define_singleton_method(
cDate,
"weeknum", date_s_weeknum, -1);
9300 de_define_singleton_method(
cDate,
"nth_kday", date_s_nth_kday, -1);
9324 #define de_define_method rb_define_method
9325 de_define_method(
cDate,
"initialize", d_lite_initialize, -1);
9330 de_define_method(
cDate,
"fill", d_lite_fill, 0);
9352 de_define_private_method(
cDate,
"wnum0", d_lite_wnum0, 0);
9353 de_define_private_method(
cDate,
"wnum1", d_lite_wnum1, 0);
9367 de_define_method(
cDate,
"nth_kday?", d_lite_nth_kday_p, 2);
9420 de_define_method(
cDate,
"inspect_raw", d_lite_inspect_raw, 0);
9437 de_define_method(
cDate,
"marshal_dump_old", d_lite_marshal_dump_old, 0);
9455 de_define_singleton_method(
cDateTime,
"weeknum",
9456 datetime_s_weeknum, -1);
9457 de_define_singleton_method(
cDateTime,
"nth_kday",
9458 datetime_s_nth_kday, -1);
9485 #define f_public(m,s) rb_funcall(m, rb_intern("public"), 1,\
9486 ID2SYM(rb_intern(s)))
9525 de_define_singleton_method(
cDate,
"test_civil", date_s_test_civil, 0);
9526 de_define_singleton_method(
cDate,
"test_ordinal", date_s_test_ordinal, 0);
9527 de_define_singleton_method(
cDate,
"test_commercial",
9528 date_s_test_commercial, 0);
9529 de_define_singleton_method(
cDate,
"test_weeknum", date_s_test_weeknum, 0);
9530 de_define_singleton_method(
cDate,
"test_nth_kday", date_s_test_nth_kday, 0);
9531 de_define_singleton_method(
cDate,
"test_unit_conv",
9532 date_s_test_unit_conv, 0);
9533 de_define_singleton_method(
cDate,
"test_all", date_s_test_all, 0);