14 #include RUBY_EXTCONF_H
24 #define f_boolcast(x) ((x) ? Qtrue : Qfalse)
26 #define f_abs(x) rb_funcall(x, rb_intern("abs"), 0)
27 #define f_negate(x) rb_funcall(x, rb_intern("-@"), 0)
28 #define f_add(x,y) rb_funcall(x, '+', 1, y)
29 #define f_sub(x,y) rb_funcall(x, '-', 1, y)
30 #define f_mul(x,y) rb_funcall(x, '*', 1, y)
31 #define f_div(x,y) rb_funcall(x, '/', 1, y)
32 #define f_quo(x,y) rb_funcall(x, rb_intern("quo"), 1, y)
33 #define f_idiv(x,y) rb_funcall(x, rb_intern("div"), 1, y)
34 #define f_mod(x,y) rb_funcall(x, '%', 1, y)
35 #define f_remainder(x,y) rb_funcall(x, rb_intern("remainder"), 1, y)
36 #define f_expt(x,y) rb_funcall(x, rb_intern("**"), 1, y)
37 #define f_floor(x) rb_funcall(x, rb_intern("floor"), 0)
38 #define f_ceil(x) rb_funcall(x, rb_intern("ceil"), 0)
39 #define f_truncate(x) rb_funcall(x, rb_intern("truncate"), 0)
40 #define f_round(x) rb_funcall(x, rb_intern("round"), 0)
42 #define f_to_i(x) rb_funcall(x, rb_intern("to_i"), 0)
43 #define f_to_r(x) rb_funcall(x, rb_intern("to_r"), 0)
44 #define f_to_s(x) rb_funcall(x, rb_intern("to_s"), 0)
45 #define f_inspect(x) rb_funcall(x, rb_intern("inspect"), 0)
47 #define f_add3(x,y,z) f_add(f_add(x, y), z)
48 #define f_sub3(x,y,z) f_sub(f_sub(x, y), z)
121 #define f_nonzero_p(x) (!f_zero_p(x))
131 #define f_positive_p(x) (!f_negative_p(x))
133 #define f_ajd(x) rb_funcall(x, rb_intern("ajd"), 0)
134 #define f_jd(x) rb_funcall(x, rb_intern("jd"), 0)
135 #define f_year(x) rb_funcall(x, rb_intern("year"), 0)
136 #define f_mon(x) rb_funcall(x, rb_intern("mon"), 0)
137 #define f_mday(x) rb_funcall(x, rb_intern("mday"), 0)
138 #define f_wday(x) rb_funcall(x, rb_intern("wday"), 0)
139 #define f_hour(x) rb_funcall(x, rb_intern("hour"), 0)
140 #define f_min(x) rb_funcall(x, rb_intern("min"), 0)
141 #define f_sec(x) rb_funcall(x, rb_intern("sec"), 0)
144 #define NDIV(x,y) (-(-((x)+1)/(y))-1)
145 #define NMOD(x,y) ((y)-(-((x)+1)%(y))-1)
146 #define DIV(n,d) ((n)<0 ? NDIV((n),(d)) : (n)/(d))
147 #define MOD(n,d) ((n)<0 ? NMOD((n),(d)) : (n)%(d))
149 #define HAVE_JD (1 << 0)
150 #define HAVE_DF (1 << 1)
151 #define HAVE_CIVIL (1 << 2)
152 #define HAVE_TIME (1 << 3)
153 #define COMPLEX_DAT (1 << 7)
155 #define have_jd_p(x) ((x)->flags & HAVE_JD)
156 #define have_df_p(x) ((x)->flags & HAVE_DF)
157 #define have_civil_p(x) ((x)->flags & HAVE_CIVIL)
158 #define have_time_p(x) ((x)->flags & HAVE_TIME)
159 #define complex_dat_p(x) ((x)->flags & COMPLEX_DAT)
160 #define simple_dat_p(x) (!complex_dat_p(x))
162 #define ITALY 2299161
163 #define ENGLAND 2361222
164 #define JULIAN positive_inf
165 #define GREGORIAN negative_inf
166 #define DEFAULT_SG ITALY
168 #define UNIX_EPOCH_IN_CJD INT2FIX(2440588)
170 #define MINUTE_IN_SECONDS 60
171 #define HOUR_IN_SECONDS 3600
172 #define DAY_IN_SECONDS 86400
173 #define SECOND_IN_MILLISECONDS 1000
174 #define SECOND_IN_NANOSECONDS 1000000000
176 #define JC_PERIOD0 1461
177 #define GC_PERIOD0 146097
178 #define CM_PERIOD0 71149239
179 #define CM_PERIOD (0xfffffff / CM_PERIOD0 * CM_PERIOD0)
180 #define CM_PERIOD_JCY (CM_PERIOD / JC_PERIOD0 * 4)
181 #define CM_PERIOD_GCY (CM_PERIOD / GC_PERIOD0 * 400)
183 #define REFORM_BEGIN_YEAR 1582
184 #define REFORM_END_YEAR 1930
185 #define REFORM_BEGIN_JD 2298874
186 #define REFORM_END_JD 2426355
196 #define MIN_SHIFT SEC_WIDTH
197 #define HOUR_SHIFT (MIN_WIDTH + SEC_WIDTH)
198 #define MDAY_SHIFT (HOUR_WIDTH + MIN_WIDTH + SEC_WIDTH)
199 #define MON_SHIFT (MDAY_WIDTH + HOUR_WIDTH + MIN_WIDTH + SEC_WIDTH)
201 #define PK_MASK(x) ((1 << (x)) - 1)
203 #define EX_SEC(x) (((x) >> SEC_SHIFT) & PK_MASK(SEC_WIDTH))
204 #define EX_MIN(x) (((x) >> MIN_SHIFT) & PK_MASK(MIN_WIDTH))
205 #define EX_HOUR(x) (((x) >> HOUR_SHIFT) & PK_MASK(HOUR_WIDTH))
206 #define EX_MDAY(x) (((x) >> MDAY_SHIFT) & PK_MASK(MDAY_WIDTH))
207 #define EX_MON(x) (((x) >> MON_SHIFT) & PK_MASK(MON_WIDTH))
209 #define PACK5(m,d,h,min,s) \
210 (((m) << MON_SHIFT) | ((d) << MDAY_SHIFT) |\
211 ((h) << HOUR_SHIFT) | ((min) << MIN_SHIFT) | ((s) << SEC_SHIFT))
214 (((m) << MON_SHIFT) | ((d) << MDAY_SHIFT))
221 #if defined(FLT_RADIX) && defined(FLT_MANT_DIG)
222 #if FLT_RADIX == 2 && FLT_MANT_DIG > 22
224 #define sg_cast float
226 #define sg_cast double
296 union DateData *dat;\
297 Data_Get_Struct(x, union DateData, dat);
300 union DateData *adat;\
301 Data_Get_Struct(x, union DateData, adat);
304 union DateData *bdat;\
305 Data_Get_Struct(x, union DateData, bdat);
308 union DateData *adat, *bdat;\
309 Data_Get_Struct(x, union DateData, adat);\
310 Data_Get_Struct(y, union DateData, bdat);
324 #define set_to_simple(x, _nth, _jd ,_sg, _year, _mon, _mday, _flags) \
326 (x)->nth = canon(_nth);\
328 (x)->sg = (sg_cast)(_sg);\
332 (x)->flags = _flags;\
335 #define set_to_simple(x, _nth, _jd ,_sg, _year, _mon, _mday, _flags) \
337 (x)->nth = canon(_nth);\
339 (x)->sg = (sg_cast)(_sg);\
341 (x)->pc = PACK2(_mon, _mday);\
342 (x)->flags = _flags;\
347 #define set_to_complex(x, _nth, _jd ,_df, _sf, _of, _sg,\
348 _year, _mon, _mday, _hour, _min, _sec, _flags) \
350 (x)->nth = canon(_nth);\
353 (x)->sf = canon(_sf);\
355 (x)->sg = (sg_cast)(_sg);\
362 (x)->flags = _flags;\
365 #define set_to_complex(x, _nth, _jd ,_df, _sf, _of, _sg,\
366 _year, _mon, _mday, _hour, _min, _sec, _flags) \
368 (x)->nth = canon(_nth);\
371 (x)->sf = canon(_sf);\
373 (x)->sg = (sg_cast)(_sg);\
375 (x)->pc = PACK5(_mon, _mday, _hour, _min, _sec);\
376 (x)->flags = _flags;\
381 #define copy_simple_to_complex(x, y) \
383 (x)->nth = (y)->nth;\
386 (x)->sf = INT2FIX(0);\
388 (x)->sg = (sg_cast)((y)->sg);\
389 (x)->year = (y)->year;\
390 (x)->mon = (y)->mon;\
391 (x)->mday = (y)->mday;\
395 (x)->flags = (y)->flags;\
398 #define copy_simple_to_complex(x, y) \
400 (x)->nth = (y)->nth;\
403 (x)->sf = INT2FIX(0);\
405 (x)->sg = (sg_cast)((y)->sg);\
406 (x)->year = (y)->year;\
407 (x)->pc = PACK5(EX_MON((y)->pc), EX_MDAY((y)->pc), 0, 0, 0);\
408 (x)->flags = (y)->flags;\
413 #define copy_complex_to_simple(x, y) \
415 (x)->nth = (y)->nth;\
417 (x)->sg = (sg_cast)((y)->sg);\
418 (x)->year = (y)->year;\
419 (x)->mon = (y)->mon;\
420 (x)->mday = (y)->mday;\
421 (x)->flags = (y)->flags;\
424 #define copy_complex_to_simple(x, y) \
426 (x)->nth = (y)->nth;\
428 (x)->sg = (sg_cast)((y)->sg);\
429 (x)->year = (y)->year;\
430 (x)->pc = PACK2(EX_MON((y)->pc), EX_MDAY((y)->pc));\
431 (x)->flags = (y)->flags;\
438 int *,
int *,
int *,
int *);
445 for (d = 1; d < 31; d++)
456 for (i = 0; i < 30; i++)
464 c_find_fdom(
int y,
int m,
double sg,
int *rjd,
int *ns)
468 for (d = 1; d < 31; d++)
480 for (i = 0; i < 30; i++)
495 a = floor(y / 100.0);
496 b = 2 - a + floor(a / 4.0);
497 jd = floor(365.25 * (y + 4716)) +
498 floor(30.6001 * (m + 1)) +
513 double x, a, b, c, d, e, y, m, dom;
518 x = floor((jd - 1867216.25) / 36524.25);
519 a = jd + 1 + x - floor(x / 4.0);
522 c = floor((b - 122.1) / 365.25);
523 d = floor(365.25 * c);
524 e = floor((b - d) / 30.6001);
525 dom = b - d - floor(30.6001 * e);
547 *ns = (*rjd <
sg) ? 0 : 1;
553 int rm2, rd2, rjd, ns;
557 *rd = (jd - rjd) + 1;
568 (rjd2 -
MOD((rjd2 - 1) + 1, 7)) +
571 *ns = (*rjd <
sg) ? 0 : 1;
577 int ry2, rm2, rd2, a, rjd2, ns2;
588 *rw = 1 +
DIV(jd - rjd2, 7);
589 *rd =
MOD(jd + 1, 7);
601 *rjd = (rjd2 -
MOD(((rjd2 - f) + 1), 7) - 7) + 7 * w + d;
602 *ns = (*rjd <
sg) ? 0 : 1;
608 int rm, rd2, rjd, ns, j;
613 j = jd - (rjd -
MOD((rjd - f) + 1, 7)) + 7;
614 *rw = (int)
DIV(j, 7);
615 *rd = (int)
MOD(j, 7);
620 c_nth_kday_to_jd(
int y,
int m,
int n,
int k,
double sg,
int *rjd,
int *ns)
625 c_find_fdom(y, m, sg, &rjd2, &ns2);
632 *rjd = (rjd2 -
MOD((rjd2 - k) + 1, 7)) + 7 * n;
633 *ns = (*rjd <
sg) ? 0 : 1;
640 return MOD(jd + 1, 7);
645 c_jd_to_nth_kday(
int jd,
double sg,
int *ry,
int *rm,
int *rn,
int *rk)
650 c_find_fdom(*ry, *rm, sg, &rjd, &ns2);
651 *rn =
DIV(jd - rjd, 7) + 1;
658 int *rd,
int *rjd,
int *ns)
674 if (ry2 != y || rd2 != d)
680 { 0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 },
681 { 0, 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 }
687 return MOD(y, 4) == 0;
693 return MOD(y, 4) == 0 && y % 100 != 0 ||
MOD(y, 400) == 0;
699 assert(m >= 1 && m <= 12);
706 assert(m >= 1 && m <= 12);
722 if (d < 1 || d > last)
741 if (d < 1 || d > last)
750 int *rm,
int *rd,
int *rjd,
int *ns)
760 if (ry != y || *rm != m)
766 if (ry != y || *rm != m || *rd != d)
773 int *rw,
int *rd,
int *rjd,
int *ns)
775 int ns2, ry2, rw2, rd2;
790 if (y != ry2 || w != *rw || d != *rd)
797 int *rw,
int *rd,
int *rjd,
int *ns)
799 int ns2, ry2, rw2, rd2;
814 if (y != ry2 || w != *rw || d != *rd)
821 c_valid_nth_kday_p(
int y,
int m,
int n,
int k,
double sg,
822 int *rm,
int *rn,
int *rk,
int *rjd,
int *ns)
824 int ns2, ry2, rm2, rn2, rk2;
835 c_nth_kday_to_jd(ny, nm, 1, k, sg, &rjd2, &ns2);
836 c_jd_to_nth_kday(rjd2 + n * 7, sg, &ry2, &rm2, &rn2, &rk2);
837 if (ry2 != y || rm2 != m)
841 c_nth_kday_to_jd(y, m, n, k, sg, rjd, ns);
842 c_jd_to_nth_kday(*rjd, sg, &ry2, rm, rn, rk);
843 if (y != ry2 || m != *rm || n != *rn || k != *rk)
861 return !(h < 0 || h > 24 ||
862 min < 0 || min > 59 ||
864 (h == 24 && (min > 0 || s > 0)));
1085 inline static double
1097 inline static double
1109 inline static double
1118 #define canonicalize_jd(_nth, _jd) \
1121 _nth = f_sub(_nth, INT2FIX(1));\
1124 if (_jd >= CM_PERIOD) {\
1125 _nth = f_add(_nth, INT2FIX(1));\
1211 int r, m, d, h,
min, s;
1274 int jd, y, m, d, h,
min, s;
1319 period = (style < 0) ?
1329 inth =
DIV(it, ((
long)period));
1332 it =
MOD(it, ((
long)period));
1333 *ry = (int)it - 4712;
1351 period = (style < 0) ?
1386 inline static double
1516 m_local_df_in_day(
union DateData *x)
1563 #define HALF_DAYS_IN_SECONDS (DAY_IN_SECONDS / 2)
1643 inline static double
1687 if (
isinf(sg) && sg > 0)
1698 if (
isinf(sg) && sg < 0)
1794 { 0, 0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334 },
1795 { 0, 0, 31, 60, 91, 121, 152, 182, 213, 244, 274, 305, 335 }
1801 assert(m >= 1 && m <= 12);
1808 assert(m >= 1 && m <= 12);
1952 #define decode_offset(of,s,h,m)\
1955 s = (of < 0) ? '-' : '+';\
1956 a = (of < 0) ? -of : of;\
1957 h = a / HOUR_IN_SECONDS;\
1958 m = a % HOUR_IN_SECONDS / MINUTE_IN_SECONDS;\
2010 civil_to_jd(
VALUE y,
int m,
int d,
double sg,
2036 jd_to_civil(
VALUE jd,
double sg,
2037 VALUE *nth,
int *rjd,
2038 int *ry,
int *rm,
int *rd)
2045 ordinal_to_jd(
VALUE y,
int d,
double sg,
2046 VALUE *nth,
int *ry,
2071 jd_to_ordinal(
VALUE jd,
double sg,
2072 VALUE *nth,
int *rjd,
2080 commercial_to_jd(
VALUE y,
int w,
int d,
double sg,
2081 VALUE *nth,
int *ry,
2106 jd_to_commercial(
VALUE jd,
double sg,
2107 VALUE *nth,
int *rjd,
2108 int *ry,
int *rw,
int *rd)
2115 weeknum_to_jd(
VALUE y,
int w,
int d,
int f,
double sg,
2116 VALUE *nth,
int *ry,
2141 jd_to_weeknum(
VALUE jd,
int f,
double sg,
2142 VALUE *nth,
int *rjd,
2143 int *ry,
int *rw,
int *rd)
2150 nth_kday_to_jd(
VALUE y,
int m,
int n,
int k,
double sg,
2151 VALUE *nth,
int *ry,
2160 c_nth_kday_to_jd(
FIX2INT(y), m, n, k, sg, &jd, ns);
2171 c_nth_kday_to_jd(*ry, m, n, k, style, rjd, ns);
2176 jd_to_nth_kday(
VALUE jd,
double sg,
2177 VALUE *nth,
int *rjd,
2178 int *ry,
int *rm,
int *rn,
int *rk)
2181 c_jd_to_nth_kday(*rjd, sg, ry, rm, rn, rk);
2187 VALUE *nth,
int *ry,
2217 VALUE *nth,
int *ry,
2226 VALUE *nth,
int *ry,
2227 int *rm,
int *rd,
int *rjd,
2262 VALUE *nth,
int *ry,
2263 int *rw,
int *rd,
int *rjd,
2292 VALUE *nth,
int *ry,
2293 int *rw,
int *rd,
int *rjd,
2322 valid_nth_kday_p(
VALUE y,
int m,
int n,
int k,
double sg,
2323 VALUE *nth,
int *ry,
2324 int *rm,
int *rn,
int *rk,
int *rjd,
2333 r = c_valid_nth_kday_p(
FIX2INT(y), m, n, k, sg, rm, rn, rk, &jd, ns);
2346 r = c_valid_nth_kday_p(*ry, m, n, k, style, rm, rn, rk, rjd, ns);
2357 switch (
TYPE(vof)) {
2363 if (n != -1 && n != 0 && n != 1)
2375 *rof = (int)
round(n);
2384 #ifdef CANONICALIZATION_FOR_MATHN
2396 #ifdef CANONICALIZATION_FOR_MATHN
2444 #define valid_sg(sg) \
2446 if (!c_valid_start_p(sg)) {\
2448 rb_warning("invalid start is ignored");\
2514 int m, d, ry, rm, rd;
2549 date_s__valid_civil_p(
int argc,
VALUE *argv,
VALUE klass)
2551 VALUE vy, vm, vd, vsg;
2585 VALUE vy, vm, vd, vsg;
2634 date_s__valid_ordinal_p(
int argc,
VALUE *argv,
VALUE klass)
2689 int w, d, ry, rw, rd;
2717 date_s__valid_commercial_p(
int argc,
VALUE *argv,
VALUE klass)
2719 VALUE vy, vw, vd, vsg;
2752 VALUE vy, vw, vd, vsg;
2772 valid_weeknum_sub(
int argc,
VALUE *argv,
VALUE klass,
int need_jd)
2775 int w, d, f, ry, rw, rd;
2803 date_s__valid_weeknum_p(
int argc,
VALUE *argv,
VALUE klass)
2805 VALUE vy, vw, vd, vf, vsg;
2808 rb_scan_args(argc, argv,
"41", &vy, &vw, &vd, &vf, &vsg);
2819 return valid_weeknum_sub(5, argv2, klass, 1);
2823 date_s_valid_weeknum_p(
int argc,
VALUE *argv,
VALUE klass)
2825 VALUE vy, vw, vd, vf, vsg;
2828 rb_scan_args(argc, argv,
"41", &vy, &vw, &vd, &vf, &vsg);
2839 if (
NIL_P(valid_weeknum_sub(5, argv2, klass, 0)))
2845 valid_nth_kday_sub(
int argc,
VALUE *argv,
VALUE klass,
int need_jd)
2848 int m, n, k, ry, rm, rn, rk;
2861 if (!valid_nth_kday_p(y, m, n, k, sg,
2863 &rm, &rn, &rk, &rjd,
2874 date_s__valid_nth_kday_p(
int argc,
VALUE *argv,
VALUE klass)
2876 VALUE vy, vm, vn, vk, vsg;
2879 rb_scan_args(argc, argv,
"41", &vy, &vm, &vn, &vk, &vsg);
2890 return valid_nth_kday_sub(5, argv2, klass, 1);
2894 date_s_valid_nth_kday_p(
int argc,
VALUE *argv,
VALUE klass)
2896 VALUE vy, vm, vn, vk, vsg;
2899 rb_scan_args(argc, argv,
"41", &vy, &vm, &vn, &vk, &vsg);
2910 if (
NIL_P(valid_nth_kday_sub(5, argv2, klass, 0)))
2983 int y,
int m,
int d,
3003 int y,
int m,
int d,
3004 int h,
int min,
int s,
3052 int *rof,
double *rsg)
3090 date_s_new_bang(
int argc,
VALUE *argv,
VALUE klass)
3108 &nth, &jd, &df, &sf, &rof, &rsg);
3138 return round(d) == d;
3175 #define jd_trunc d_trunc
3176 #define k_trunc d_trunc
3229 #define num2num_with_frac(s,n) \
3231 s = s##_trunc(v##s, &fr);\
3232 if (f_nonzero_p(fr)) {\
3234 rb_raise(rb_eArgError, "invalid fraction");\
3239 #define num2int_with_frac(s,n) \
3241 s = NUM2INT(s##_trunc(v##s, &fr));\
3242 if (f_nonzero_p(fr)) {\
3244 rb_raise(rb_eArgError, "invalid fraction");\
3249 #define canon24oc() \
3253 fr2 = f_add(fr2, INT2FIX(1));\
3257 #define add_frac() \
3259 if (f_nonzero_p(fr2))\
3260 ret = d_lite_plus(ret, fr2);\
3263 #define val2sg(vsg,dsg) \
3265 dsg = NUM2DBL(vsg);\
3266 if (!c_valid_start_p(dsg)) {\
3268 rb_warning("invalid start is ignored");\
3292 VALUE vjd, vsg,
jd, fr, fr2, ret;
3344 VALUE vy, vd, vsg, y, fr, fr2, ret;
3366 int ry, rd, rjd, ns;
3414 VALUE vy, vm, vd, vsg, y, fr, fr2, ret;
3454 int ry, rm, rd, rjd, ns;
3493 VALUE vy, vw, vd, vsg, y, fr, fr2, ret;
3518 int ry, rw, rd, rjd, ns;
3538 date_s_weeknum(
int argc,
VALUE *argv,
VALUE klass)
3540 VALUE vy, vw, vd, vf, vsg, y, fr, fr2, ret;
3544 rb_scan_args(argc, argv,
"05", &vy, &vw, &vd, &vf, &vsg);
3568 int ry, rw, rd, rjd, ns;
3587 date_s_nth_kday(
int argc,
VALUE *argv,
VALUE klass)
3589 VALUE vy, vm, vn, vk, vsg, y, fr, fr2, ret;
3593 rb_scan_args(argc, argv,
"05", &vy, &vm, &vn, &vk, &vsg);
3617 int ry, rm, rn, rk, rjd, ns;
3619 if (!valid_nth_kday_p(y, m, n, k, sg,
3621 &rm, &rn, &rk, &rjd,
3636 #if !defined(HAVE_GMTIME_R)
3640 auto struct tm *tmp = gmtime(t);
3649 auto struct tm *tmp = localtime(t);
3671 VALUE vsg, nth, ret;
3690 y = tm.tm_year + 1900;
3708 #define set_hash0(k,v) rb_hash_aset(hash, k, v)
3709 #define ref_hash0(k) rb_hash_aref(hash, k)
3710 #define del_hash0(k) rb_hash_delete(hash, k)
3712 #define set_hash(k,v) rb_hash_aset(hash, ID2SYM(rb_intern(k)), v)
3713 #define ref_hash(k) rb_hash_aref(hash, ID2SYM(rb_intern(k)))
3714 #define del_hash(k) rb_hash_delete(hash, ID2SYM(rb_intern(k)))
3722 if (!
NIL_P(seconds)) {
3748 #define sym(x) ID2SYM(rb_intern(x))
3855 int i, eno = 0, idx = 0;
3888 if (k ==
sym(
"ordinal")) {
3897 else if (k ==
sym(
"civil")) {
3914 else if (k ==
sym(
"commercial")) {
3931 else if (k ==
sym(
"wday")) {
3938 else if (k ==
sym(
"wnum0")) {
3955 else if (k ==
sym(
"wnum1")) {
3974 if (g && k ==
sym(
"time")) {
4005 int ry, rd, rjd, ns;
4020 int ry, rm, rd, rjd, ns;
4035 int ry, rw, rd, rjd, ns;
4050 int ry, rw, rd, rjd, ns;
4086 VALUE year, mon, mday;
4098 VALUE year, week, wday;
4118 VALUE year, week, wday;
4138 VALUE year, week, wday;
4201 const char *fmt,
size_t flen,
VALUE hash);
4205 const char *default_fmt)
4208 const char *str, *fmt;
4216 "string should have ASCII compatible encoding");
4221 flen =
strlen(default_fmt);
4227 "format should have ASCII compatible encoding");
4330 "string should have ASCII compatible encoding");
4390 VALUE str, comp, sg;
4586 str =
rb_str_new2(
"Mon, 1 Jan -4712 00:00:00 +0000");
4631 str =
rb_str_new2(
"Mon, 01 Jan -4712 00:00:00 GMT");
4732 #define val2off(vof,iof) \
4734 if (!offset_to_sec(vof, &iof)) {\
4736 rb_warning("invalid offset is ignored");\
4742 d_lite_initialize(
int argc,
VALUE *argv,
VALUE self)
4744 VALUE jd, vjd, vdf, sf, vsf, vof, vsg;
4748 rb_scan_args(argc, argv,
"05", &vjd, &vdf, &vsf, &vof, &vsg);
4787 "cannot load complex into simple");
4812 "cannot load complex into simple");
4823 d_lite_fill(
VALUE self)
5079 d_lite_wnum0(
VALUE self)
5086 d_lite_wnum1(
VALUE self)
5376 int rjd, ns, ry, rm, rd;
5440 x->
s.
sg = (sg_cast)sg;
5445 x->
c.
sg = (sg_cast)sg;
5605 switch (
TYPE(other)) {
5622 jd =
m_jd(dat) + (int)t;
5636 dat->c.df, dat->c.sf,
5637 dat->c.of, dat->c.sg,
5675 jd =
m_jd(dat) + jd;
5694 dat->c.df, dat->c.sf,
5695 dat->c.of, dat->c.sg,
5768 df =
m_df(dat) + df;
5782 jd =
m_jd(dat) + jd;
5815 #ifdef CANONICALIZATION_FOR_MATHN
5871 df =
m_df(dat) + df;
5885 jd =
m_jd(dat) + jd;
5993 switch (
TYPE(other)) {
6070 VALUE t, y, nth, rjd2;
6097 &rm, &rd, &rjd, &ns))
6211 VALUE limit, step, date;
6318 a_nth =
m_nth(adat);
6319 b_nth =
m_nth(bdat);
6332 else if (
f_lt_p(a_sf, b_sf)) {
6339 else if (a_df < b_df) {
6346 else if (a_jd < b_jd) {
6353 else if (
f_lt_p(a_nth, b_nth)) {
6391 return cmp_dd(
self, other);
6400 a_nth =
m_nth(adat);
6401 b_nth =
m_nth(bdat);
6408 else if (a_jd < b_jd) {
6415 else if (a_nth < b_nth) {
6436 a_nth =
m_nth(adat);
6437 b_nth =
m_nth(bdat);
6441 if (a_year == b_year) {
6443 a_mon =
m_mon(adat);
6444 b_mon =
m_mon(bdat);
6445 if (a_mon == b_mon) {
6448 if (a_mday == b_mday) {
6451 else if (a_mday < b_mday) {
6458 else if (a_mon < b_mon) {
6470 else if (a_pd < b_pd) {
6478 else if (a_year < b_year) {
6485 else if (
f_lt_p(a_nth, b_nth)) {
6545 a_nth =
m_nth(adat);
6546 b_nth =
m_nth(bdat);
6568 a_nth =
m_nth(adat);
6569 b_nth =
m_nth(bdat);
6573 if (a_year == b_year) {
6575 a_mon =
m_mon(adat);
6576 b_mon =
m_mon(bdat);
6577 if (a_mon == b_mon) {
6580 if (a_mday == b_mday)
6646 mk_inspect_flags(
union DateData *x)
6658 mk_inspect_raw(
union DateData *x,
const char *klass)
6668 "(%sth,%dj),+0s,%.0fj; "
6670 klass ? klass :
"?",
6673 x->
s.
year, x->
s.mon, x->
s.mday,
6681 VALUE nth, sf, flags;
6689 "(%sth,%dj,%ds,%sn),%+ds,%.0fj; "
6690 "%dy%dm%dd %dh%dm%ds; %s>",
6691 klass ? klass :
"?",
6696 x->
c.
year, x->
c.mon, x->
c.mday,
6697 x->
c.hour, x->
c.min, x->
c.sec,
6709 d_lite_inspect_raw(
VALUE self)
6725 "#<%s: %s ((%sj,%ds,%sn),%+ds,%.0fj)>",
6726 klass ? klass :
"?",
6761 size_t date_strftime(
char *s,
size_t maxsize,
const char *format,
6764 #define SMALLBUF 100
6778 if (len != 0 || (**buf ==
'\0' &&
errno != ERANGE))
return len;
6779 for (size=1024; ; size*=2) {
6792 if (size >= 1024 * flen) {
6816 #define MILLISECOND_IN_NANOSECONDS 1000000
6847 (int (*)(
void *))
m_mon,
6856 (int (*)(
void *))
m_min,
6857 (int (*)(
void *))
m_sec,
6869 tmx->
dat = (
void *)dat;
6875 const char *default_fmt,
6893 "format should have ASCII compatible encoding");
6898 (*func)(
self, &tmx);
6899 if (memchr(fmt,
'\0', len)) {
6901 const char *
p = fmt, *pe = fmt +
len;
6908 if (buf != buffer) {
6912 for (fmt = p; p < pe && !*
p; ++
p);
6923 if (buf != buffer)
xfree(buf);
7122 (*func)(
self, &tmx);
7125 if (buf != buffer)
xfree(buf);
7246 d_lite_marshal_dump_old(
VALUE self)
7302 VALUE ajd, of, sg, nth, sf;
7311 &nth, &jd, &df, &sf, &rof, &rsg);
7318 "cannot load complex into simple");
7343 "cannot load complex into simple");
7384 VALUE vjd, vh, vmin, vs, vof, vsg, jd, fr, fr2, ret;
7388 rb_scan_args(argc, argv,
"06", &vjd, &vh, &vmin, &vs, &vof, &vsg);
7414 int rh, rmin, rs, rjd, rjd2;
7454 VALUE vy, vd, vh, vmin, vs, vof, vsg, y, fr, fr2, ret;
7455 int d, h,
min, s, rof;
7458 rb_scan_args(argc, argv,
"07", &vy, &vd, &vh, &vmin, &vs, &vof, &vsg);
7487 int ry, rd, rh, rmin, rs, rjd, rjd2, ns;
7532 VALUE vy, vm, vd, vh, vmin, vs, vof, vsg, y, fr, fr2, ret;
7533 int m, d, h,
min, s, rof;
7536 rb_scan_args(argc, argv,
"08", &vy, &vm, &vd, &vh, &vmin, &vs, &vof, &vsg);
7568 int ry, rm, rd, rh, rmin, rs;
7588 int ry, rm, rd, rh, rmin, rs, rjd, rjd2, ns;
7631 VALUE vy, vw, vd, vh, vmin, vs, vof, vsg, y, fr, fr2, ret;
7632 int w, d, h,
min, s, rof;
7635 rb_scan_args(argc, argv,
"08", &vy, &vw, &vd, &vh, &vmin, &vs, &vof, &vsg);
7667 int ry, rw, rd, rh, rmin, rs, rjd, rjd2, ns;
7696 datetime_s_weeknum(
int argc,
VALUE *argv,
VALUE klass)
7698 VALUE vy, vw, vd, vf, vh, vmin, vs, vof, vsg, y, fr, fr2, ret;
7699 int w, d, f, h,
min, s, rof;
7703 &vh, &vmin, &vs, &vof, &vsg);
7738 int ry, rw, rd, rh, rmin, rs, rjd, rjd2, ns;
7765 datetime_s_nth_kday(
int argc,
VALUE *argv,
VALUE klass)
7767 VALUE vy, vm, vn, vk, vh, vmin, vs, vof, vsg, y, fr, fr2, ret;
7768 int m, n, k, h,
min, s, rof;
7772 &vh, &vmin, &vs, &vof, &vsg);
7807 int ry, rm, rn, rk, rh, rmin, rs, rjd, rjd2, ns;
7809 if (!valid_nth_kday_p(y, m, n, k, sg,
7811 &rm, &rn, &rk, &rjd,
7847 VALUE vsg, nth, ret;
7849 #ifdef HAVE_CLOCK_GETTIME
7857 int y, ry, m, d, h,
min, s;
7866 #ifdef HAVE_CLOCK_GETTIME
7867 if (clock_gettime(CLOCK_REALTIME, &ts) == -1)
7879 y = tm.tm_year + 1900;
7887 #ifdef HAVE_STRUCT_TM_TM_GMTOFF
7889 #elif defined(HAVE_VAR_TIMEZONE)
7890 #ifdef HAVE_VAR_ALTZONE
7899 of += (
long)difftime(sec2, sec);
7902 #elif defined(HAVE_TIMEGM)
7907 of = (
long)difftime(sec2, sec);
7916 tm2.tm_isdst = tm.tm_isdst;
7917 sec2 = mktime(&tm2);
7918 of = (
long)difftime(sec, sec2);
7921 #ifdef HAVE_CLOCK_GETTIME
8126 VALUE str, comp, sg;
8271 str =
rb_str_new2(
"Mon, 1 Jan -4712 00:00:00 +0000");
8303 str =
rb_str_new2(
"Mon, 01 Jan -4712 00:00:00 GMT");
8545 "%Y-%m-%dT%H:%M:%S%:z",
set_tmx);
8648 #define f_getlocal(x) rb_funcall(x, rb_intern("getlocal"), 0)
8649 #define f_subsec(x) rb_funcall(x, rb_intern("subsec"), 0)
8650 #define f_utc_offset(x) rb_funcall(x, rb_intern("utc_offset"), 0)
8651 #define f_local3(x,y,m,d) rb_funcall(x, rb_intern("local"), 3, y, m, d)
8652 #define f_utc6(x,y,m,d,h,min,s) rb_funcall(x, rb_intern("utc"), 6,\
8706 VALUE y, sf, nth, ret;
8707 int ry, m, d, h,
min, s, of;
8881 #define MIN_YEAR -4713
8882 #define MAX_YEAR 1000000
8884 #define MAX_JD 366963925
8887 test_civil(
int from,
int to,
double sg)
8891 fprintf(stderr,
"test_civil: %d...%d (%d) - %.0f\n",
8892 from, to, to - from, sg);
8893 for (j = from; j <= to; j++) {
8894 int y, m, d, rj, ns;
8899 fprintf(stderr,
"%d != %d\n", j, rj);
8907 date_s_test_civil(
VALUE klass)
8909 if (!test_civil(MIN_JD, MIN_JD + 366,
GREGORIAN))
8911 if (!test_civil(2305814, 2598007,
GREGORIAN))
8913 if (!test_civil(MAX_JD - 366, MAX_JD,
GREGORIAN))
8916 if (!test_civil(MIN_JD, MIN_JD + 366,
ITALY))
8918 if (!test_civil(2305814, 2598007,
ITALY))
8920 if (!test_civil(MAX_JD - 366, MAX_JD,
ITALY))
8927 test_ordinal(
int from,
int to,
double sg)
8931 fprintf(stderr,
"test_ordinal: %d...%d (%d) - %.0f\n",
8932 from, to, to - from, sg);
8933 for (j = from; j <= to; j++) {
8939 fprintf(stderr,
"%d != %d\n", j, rj);
8947 date_s_test_ordinal(
VALUE klass)
8949 if (!test_ordinal(MIN_JD, MIN_JD + 366,
GREGORIAN))
8951 if (!test_ordinal(2305814, 2598007,
GREGORIAN))
8953 if (!test_ordinal(MAX_JD - 366, MAX_JD,
GREGORIAN))
8956 if (!test_ordinal(MIN_JD, MIN_JD + 366,
ITALY))
8958 if (!test_ordinal(2305814, 2598007,
ITALY))
8960 if (!test_ordinal(MAX_JD - 366, MAX_JD,
ITALY))
8967 test_commercial(
int from,
int to,
double sg)
8971 fprintf(stderr,
"test_commercial: %d...%d (%d) - %.0f\n",
8972 from, to, to - from, sg);
8973 for (j = from; j <= to; j++) {
8974 int y, w, d, rj, ns;
8979 fprintf(stderr,
"%d != %d\n", j, rj);
8987 date_s_test_commercial(
VALUE klass)
8989 if (!test_commercial(MIN_JD, MIN_JD + 366,
GREGORIAN))
8991 if (!test_commercial(2305814, 2598007,
GREGORIAN))
8993 if (!test_commercial(MAX_JD - 366, MAX_JD,
GREGORIAN))
8996 if (!test_commercial(MIN_JD, MIN_JD + 366,
ITALY))
8998 if (!test_commercial(2305814, 2598007,
ITALY))
9000 if (!test_commercial(MAX_JD - 366, MAX_JD,
ITALY))
9007 test_weeknum(
int from,
int to,
int f,
double sg)
9011 fprintf(stderr,
"test_weeknum: %d...%d (%d) - %.0f\n",
9012 from, to, to - from, sg);
9013 for (j = from; j <= to; j++) {
9014 int y, w, d, rj, ns;
9019 fprintf(stderr,
"%d != %d\n", j, rj);
9027 date_s_test_weeknum(
VALUE klass)
9031 for (f = 0; f <= 1; f++) {
9032 if (!test_weeknum(MIN_JD, MIN_JD + 366, f,
GREGORIAN))
9034 if (!test_weeknum(2305814, 2598007, f,
GREGORIAN))
9036 if (!test_weeknum(MAX_JD - 366, MAX_JD, f,
GREGORIAN))
9039 if (!test_weeknum(MIN_JD, MIN_JD + 366, f,
ITALY))
9041 if (!test_weeknum(2305814, 2598007, f,
ITALY))
9043 if (!test_weeknum(MAX_JD - 366, MAX_JD, f,
ITALY))
9051 test_nth_kday(
int from,
int to,
double sg)
9055 fprintf(stderr,
"test_nth_kday: %d...%d (%d) - %.0f\n",
9056 from, to, to - from, sg);
9057 for (j = from; j <= to; j++) {
9058 int y, m, n, k, rj, ns;
9060 c_jd_to_nth_kday(j, sg, &y, &m, &n, &k);
9061 c_nth_kday_to_jd(y, m, n, k, sg, &rj, &ns);
9063 fprintf(stderr,
"%d != %d\n", j, rj);
9071 date_s_test_nth_kday(
VALUE klass)
9073 if (!test_nth_kday(MIN_JD, MIN_JD + 366,
GREGORIAN))
9075 if (!test_nth_kday(2305814, 2598007,
GREGORIAN))
9077 if (!test_nth_kday(MAX_JD - 366, MAX_JD,
GREGORIAN))
9080 if (!test_nth_kday(MIN_JD, MIN_JD + 366,
ITALY))
9082 if (!test_nth_kday(2305814, 2598007,
ITALY))
9084 if (!test_nth_kday(MAX_JD - 366, MAX_JD,
ITALY))
9105 if (!test_unit_v2v(
INT2FIX(0), conv1, conv2))
9107 if (!test_unit_v2v(
INT2FIX(1), conv1, conv2))
9109 if (!test_unit_v2v(
INT2FIX(2), conv1, conv2))
9111 if (!test_unit_v2v(
INT2FIX(3), conv1, conv2))
9113 if (!test_unit_v2v(
INT2FIX(11), conv1, conv2))
9115 if (!test_unit_v2v(
INT2FIX(65535), conv1, conv2))
9117 if (!test_unit_v2v(
INT2FIX(1073741823), conv1, conv2))
9119 if (!test_unit_v2v(
INT2NUM(1073741824), conv1, conv2))
9136 if (!test_unit_v2v_iter2(conv1, conv2))
9138 if (!test_unit_v2v_iter2(conv2, conv1))
9144 date_s_test_unit_conv(
VALUE klass)
9148 if (!test_unit_v2v_iter(ms_to_sec,
sec_to_ms))
9150 if (!test_unit_v2v_iter(
ns_to_day, day_to_ns))
9158 date_s_test_all(
VALUE klass)
9160 if (date_s_test_civil(klass) ==
Qfalse)
9162 if (date_s_test_ordinal(klass) ==
Qfalse)
9164 if (date_s_test_commercial(klass) ==
Qfalse)
9166 if (date_s_test_weeknum(klass) ==
Qfalse)
9168 if (date_s_test_nth_kday(klass) ==
Qfalse)
9170 if (date_s_test_unit_conv(klass) ==
Qfalse)
9178 "January",
"February",
"March",
9179 "April",
"May",
"June",
9180 "July",
"August",
"September",
9181 "October",
"November",
"December"
9186 "Jan",
"Feb",
"Mar",
"Apr",
9187 "May",
"Jun",
"Jul",
"Aug",
9188 "Sep",
"Oct",
"Nov",
"Dec"
9192 "Sunday",
"Monday",
"Tuesday",
"Wednesday",
9193 "Thursday",
"Friday",
"Saturday"
9197 "Sun",
"Mon",
"Tue",
"Wed",
9208 for (i = 0; i <
len; i++) {
9227 #define rb_intern(str) rb_intern_const(str)
9229 assert(fprintf(stderr,
"assert() is now active\n"));
9238 #if (LONG_MAX / DAY_IN_SECONDS) > SECOND_IN_NANOSECONDS
9241 #elif defined HAVE_LONG_LONG
9243 SECOND_IN_NANOSECONDS);
9246 INT2FIX(SECOND_IN_NANOSECONDS));
9503 #define de_define_private_method rb_define_private_method
9505 date_s__valid_jd_p, -1);
9506 de_define_private_method(
CLASS_OF(
cDate),
"_valid_ordinal?",
9507 date_s__valid_ordinal_p, -1);
9509 date_s__valid_civil_p, -1);
9511 date_s__valid_civil_p, -1);
9512 de_define_private_method(
CLASS_OF(
cDate),
"_valid_commercial?",
9513 date_s__valid_commercial_p, -1);
9514 de_define_private_method(
CLASS_OF(
cDate),
"_valid_weeknum?",
9515 date_s__valid_weeknum_p, -1);
9516 de_define_private_method(
CLASS_OF(
cDate),
"_valid_nth_kday?",
9517 date_s__valid_nth_kday_p, -1);
9530 date_s_valid_weeknum_p, -1);
9531 de_define_private_method(
CLASS_OF(
cDate),
"valid_nth_kday?",
9532 date_s_valid_nth_kday_p, -1);
9534 date_s_zone_to_diff, 1);
9544 #define de_define_singleton_method rb_define_singleton_method
9545 #define de_define_alias rb_define_alias
9546 de_define_singleton_method(
cDate,
"new!", date_s_new_bang, -1);
9557 de_define_singleton_method(
cDate,
"weeknum", date_s_weeknum, -1);
9558 de_define_singleton_method(
cDate,
"nth_kday", date_s_nth_kday, -1);
9582 #define de_define_method rb_define_method
9583 de_define_method(
cDate,
"initialize", d_lite_initialize, -1);
9588 de_define_method(
cDate,
"fill", d_lite_fill, 0);
9610 de_define_private_method(
cDate,
"wnum0", d_lite_wnum0, 0);
9611 de_define_private_method(
cDate,
"wnum1", d_lite_wnum1, 0);
9625 de_define_method(
cDate,
"nth_kday?", d_lite_nth_kday_p, 2);
9678 de_define_method(
cDate,
"inspect_raw", d_lite_inspect_raw, 0);
9695 de_define_method(
cDate,
"marshal_dump_old", d_lite_marshal_dump_old, 0);
9712 de_define_singleton_method(
cDateTime,
"weeknum",
9713 datetime_s_weeknum, -1);
9714 de_define_singleton_method(
cDateTime,
"nth_kday",
9715 datetime_s_nth_kday, -1);
9742 #define f_public(m,s) rb_funcall(m, rb_intern("public"), 1,\
9743 ID2SYM(rb_intern(s)))
9782 de_define_singleton_method(
cDate,
"test_civil", date_s_test_civil, 0);
9783 de_define_singleton_method(
cDate,
"test_ordinal", date_s_test_ordinal, 0);
9784 de_define_singleton_method(
cDate,
"test_commercial",
9785 date_s_test_commercial, 0);
9786 de_define_singleton_method(
cDate,
"test_weeknum", date_s_test_weeknum, 0);
9787 de_define_singleton_method(
cDate,
"test_nth_kday", date_s_test_nth_kday, 0);
9788 de_define_singleton_method(
cDate,
"test_unit_conv",
9789 date_s_test_unit_conv, 0);
9790 de_define_singleton_method(
cDate,
"test_all", date_s_test_all, 0);