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)));
1079 inline static double
1091 inline static double
1103 inline static double
1183 int r, m, d, h,
min, s;
1236 int jd, y, m, d, h,
min, s;
1281 period = (style < 0) ?
1291 inth =
DIV(it, ((
long)period));
1294 it =
MOD(it, ((
long)period));
1295 *ry = (int)it - 4712;
1313 period = (style < 0) ?
1348 inline static double
1465 m_local_df_in_day(
union DateData *x)
1512 #define HALF_DAYS_IN_SECONDS (DAY_IN_SECONDS / 2)
1592 inline static double
1636 if (
isinf(sg) && sg > 0)
1647 if (
isinf(sg) && sg < 0)
1743 { 0, 0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334 },
1744 { 0, 0, 31, 60, 91, 121, 152, 182, 213, 244, 274, 305, 335 }
1750 assert(m >= 1 && m <= 12);
1757 assert(m >= 1 && m <= 12);
1901 #define decode_offset(of,s,h,m)\
1904 s = (of < 0) ? '-' : '+';\
1905 a = (of < 0) ? -of : of;\
1906 h = a / HOUR_IN_SECONDS;\
1907 m = a % HOUR_IN_SECONDS / MINUTE_IN_SECONDS;\
1959 civil_to_jd(
VALUE y,
int m,
int d,
double sg,
1985 jd_to_civil(
VALUE jd,
double sg,
1986 VALUE *nth,
int *rjd,
1987 int *ry,
int *rm,
int *rd)
1994 ordinal_to_jd(
VALUE y,
int d,
double sg,
1995 VALUE *nth,
int *ry,
2020 jd_to_ordinal(
VALUE jd,
double sg,
2021 VALUE *nth,
int *rjd,
2029 commercial_to_jd(
VALUE y,
int w,
int d,
double sg,
2030 VALUE *nth,
int *ry,
2055 jd_to_commercial(
VALUE jd,
double sg,
2056 VALUE *nth,
int *rjd,
2057 int *ry,
int *rw,
int *rd)
2064 weeknum_to_jd(
VALUE y,
int w,
int d,
int f,
double sg,
2065 VALUE *nth,
int *ry,
2090 jd_to_weeknum(
VALUE jd,
int f,
double sg,
2091 VALUE *nth,
int *rjd,
2092 int *ry,
int *rw,
int *rd)
2099 nth_kday_to_jd(
VALUE y,
int m,
int n,
int k,
double sg,
2100 VALUE *nth,
int *ry,
2109 c_nth_kday_to_jd(
FIX2INT(y), m, n, k, sg, &jd, ns);
2120 c_nth_kday_to_jd(*ry, m, n, k, style, rjd, ns);
2125 jd_to_nth_kday(
VALUE jd,
double sg,
2126 VALUE *nth,
int *rjd,
2127 int *ry,
int *rm,
int *rn,
int *rk)
2130 c_jd_to_nth_kday(*rjd, sg, ry, rm, rn, rk);
2136 VALUE *nth,
int *ry,
2166 VALUE *nth,
int *ry,
2175 VALUE *nth,
int *ry,
2176 int *rm,
int *rd,
int *rjd,
2211 VALUE *nth,
int *ry,
2212 int *rw,
int *rd,
int *rjd,
2241 VALUE *nth,
int *ry,
2242 int *rw,
int *rd,
int *rjd,
2271 valid_nth_kday_p(
VALUE y,
int m,
int n,
int k,
double sg,
2272 VALUE *nth,
int *ry,
2273 int *rm,
int *rn,
int *rk,
int *rjd,
2282 r = c_valid_nth_kday_p(
FIX2INT(y), m, n, k, sg, rm, rn, rk, &jd, ns);
2295 r = c_valid_nth_kday_p(*ry, m, n, k, style, rm, rn, rk, rjd, ns);
2306 switch (
TYPE(vof)) {
2312 if (n != -1 && n != 0 && n != 1)
2324 *rof = (int)
round(n);
2333 #ifdef CANONICALIZATION_FOR_MATHN
2345 #ifdef CANONICALIZATION_FOR_MATHN
2393 #define valid_sg(sg) \
2395 if (!c_valid_start_p(sg)) {\
2397 rb_warning("invalid start is ignored");\
2463 int m, d, ry, rm, rd;
2498 date_s__valid_civil_p(
int argc,
VALUE *argv,
VALUE klass)
2500 VALUE vy, vm, vd, vsg;
2534 VALUE vy, vm, vd, vsg;
2583 date_s__valid_ordinal_p(
int argc,
VALUE *argv,
VALUE klass)
2638 int w, d, ry, rw, rd;
2666 date_s__valid_commercial_p(
int argc,
VALUE *argv,
VALUE klass)
2668 VALUE vy, vw, vd, vsg;
2701 VALUE vy, vw, vd, vsg;
2721 valid_weeknum_sub(
int argc,
VALUE *argv,
VALUE klass,
int need_jd)
2724 int w, d, f, ry, rw, rd;
2752 date_s__valid_weeknum_p(
int argc,
VALUE *argv,
VALUE klass)
2754 VALUE vy, vw, vd, vf, vsg;
2757 rb_scan_args(argc, argv,
"41", &vy, &vw, &vd, &vf, &vsg);
2768 return valid_weeknum_sub(5, argv2, klass, 1);
2772 date_s_valid_weeknum_p(
int argc,
VALUE *argv,
VALUE klass)
2774 VALUE vy, vw, vd, vf, vsg;
2777 rb_scan_args(argc, argv,
"41", &vy, &vw, &vd, &vf, &vsg);
2788 if (
NIL_P(valid_weeknum_sub(5, argv2, klass, 0)))
2794 valid_nth_kday_sub(
int argc,
VALUE *argv,
VALUE klass,
int need_jd)
2797 int m, n, k, ry, rm, rn, rk;
2810 if (!valid_nth_kday_p(y, m, n, k, sg,
2812 &rm, &rn, &rk, &rjd,
2823 date_s__valid_nth_kday_p(
int argc,
VALUE *argv,
VALUE klass)
2825 VALUE vy, vm, vn, vk, vsg;
2828 rb_scan_args(argc, argv,
"41", &vy, &vm, &vn, &vk, &vsg);
2839 return valid_nth_kday_sub(5, argv2, klass, 1);
2843 date_s_valid_nth_kday_p(
int argc,
VALUE *argv,
VALUE klass)
2845 VALUE vy, vm, vn, vk, vsg;
2848 rb_scan_args(argc, argv,
"41", &vy, &vm, &vn, &vk, &vsg);
2859 if (
NIL_P(valid_nth_kday_sub(5, argv2, klass, 0)))
2932 int y,
int m,
int d,
2952 int y,
int m,
int d,
2953 int h,
int min,
int s,
3001 int *rof,
double *rsg)
3039 date_s_new_bang(
int argc,
VALUE *argv,
VALUE klass)
3057 &nth, &jd, &df, &sf, &rof, &rsg);
3087 return round(d) == d;
3124 #define jd_trunc d_trunc
3125 #define k_trunc d_trunc
3178 #define num2num_with_frac(s,n) \
3180 s = s##_trunc(v##s, &fr);\
3181 if (f_nonzero_p(fr)) {\
3183 rb_raise(rb_eArgError, "invalid fraction");\
3188 #define num2int_with_frac(s,n) \
3190 s = NUM2INT(s##_trunc(v##s, &fr));\
3191 if (f_nonzero_p(fr)) {\
3193 rb_raise(rb_eArgError, "invalid fraction");\
3198 #define canon24oc() \
3202 fr2 = f_add(fr2, INT2FIX(1));\
3206 #define add_frac() \
3208 if (f_nonzero_p(fr2))\
3209 ret = d_lite_plus(ret, fr2);\
3212 #define val2sg(vsg,dsg) \
3214 dsg = NUM2DBL(vsg);\
3215 if (!c_valid_start_p(dsg)) {\
3217 rb_warning("invalid start is ignored");\
3241 VALUE vjd, vsg,
jd, fr, fr2, ret;
3293 VALUE vy, vd, vsg, y, fr, fr2, ret;
3315 int ry, rd, rjd, ns;
3363 VALUE vy, vm, vd, vsg, y, fr, fr2, ret;
3403 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);
3620 VALUE vsg, nth, ret;
3639 y = tm.tm_year + 1900;
3657 #define set_hash0(k,v) rb_hash_aset(hash, k, v)
3658 #define ref_hash0(k) rb_hash_aref(hash, k)
3659 #define del_hash0(k) rb_hash_delete(hash, k)
3661 #define set_hash(k,v) rb_hash_aset(hash, ID2SYM(rb_intern(k)), v)
3662 #define ref_hash(k) rb_hash_aref(hash, ID2SYM(rb_intern(k)))
3663 #define del_hash(k) rb_hash_delete(hash, ID2SYM(rb_intern(k)))
3671 if (!
NIL_P(seconds)) {
3697 #define sym(x) ID2SYM(rb_intern(x))
3804 int i, eno = 0, idx = 0;
3837 if (k ==
sym(
"ordinal")) {
3846 else if (k ==
sym(
"civil")) {
3863 else if (k ==
sym(
"commercial")) {
3880 else if (k ==
sym(
"wday")) {
3887 else if (k ==
sym(
"wnum0")) {
3904 else if (k ==
sym(
"wnum1")) {
3923 if (g && k ==
sym(
"time")) {
3954 int ry, rd, rjd, ns;
3969 int ry, rm, rd, rjd, ns;
3984 int ry, rw, rd, rjd, ns;
3999 int ry, rw, rd, rjd, ns;
4035 VALUE year, mon, mday;
4047 VALUE year, week, wday;
4067 VALUE year, week, wday;
4087 VALUE year, week, wday;
4150 const char *fmt,
size_t flen,
VALUE hash);
4154 const char *default_fmt)
4157 const char *str, *fmt;
4165 "string should have ASCII compatible encoding");
4170 flen =
strlen(default_fmt);
4176 "format should have ASCII compatible encoding");
4279 "string should have ASCII compatible encoding");
4339 VALUE str, comp, sg;
4535 str =
rb_str_new2(
"Mon, 1 Jan -4712 00:00:00 +0000");
4580 str =
rb_str_new2(
"Mon, 01 Jan -4712 00:00:00 GMT");
4681 #define val2off(vof,iof) \
4683 if (!offset_to_sec(vof, &iof)) {\
4685 rb_warning("invalid offset is ignored");\
4691 d_lite_initialize(
int argc,
VALUE *argv,
VALUE self)
4693 VALUE jd, vjd, vdf, sf, vsf, vof, vsg;
4697 rb_scan_args(argc, argv,
"05", &vjd, &vdf, &vsf, &vof, &vsg);
4736 "cannot load complex into simple");
4761 "cannot load complex into simple");
4772 d_lite_fill(
VALUE self)
5028 d_lite_wnum0(
VALUE self)
5035 d_lite_wnum1(
VALUE self)
5325 int rjd, ns, ry, rm, rd;
5389 x->
s.
sg = (sg_cast)sg;
5394 x->
c.
sg = (sg_cast)sg;
5554 switch (
TYPE(other)) {
5571 jd =
m_jd(dat) + (int)t;
5593 dat->c.df, dat->c.sf,
5594 dat->c.of, dat->c.sg,
5632 jd =
m_jd(dat) + jd;
5658 dat->c.df, dat->c.sf,
5659 dat->c.of, dat->c.sg,
5732 df =
m_df(dat) + df;
5746 jd =
m_jd(dat) + jd;
5786 #ifdef CANONICALIZATION_FOR_MATHN
5842 df =
m_df(dat) + df;
5856 jd =
m_jd(dat) + jd;
5979 switch (
TYPE(other)) {
6056 VALUE t, y, nth, rjd2;
6083 &rm, &rd, &rjd, &ns))
6197 VALUE limit, step, date;
6302 a_nth =
m_nth(adat);
6303 b_nth =
m_nth(bdat);
6316 else if (
f_lt_p(a_sf, b_sf)) {
6323 else if (a_df < b_df) {
6330 else if (a_jd < b_jd) {
6337 else if (
f_lt_p(a_nth, b_nth)) {
6375 return cmp_dd(
self, other);
6382 a_nth =
m_nth(adat);
6383 b_nth =
m_nth(bdat);
6390 else if (a_jd < b_jd) {
6397 else if (a_nth < b_nth) {
6416 a_nth =
m_nth(adat);
6417 b_nth =
m_nth(bdat);
6421 if (a_year == b_year) {
6423 a_mon =
m_mon(adat);
6424 b_mon =
m_mon(bdat);
6425 if (a_mon == b_mon) {
6428 if (a_mday == b_mday) {
6431 else if (a_mday < b_mday) {
6438 else if (a_mon < b_mon) {
6450 else if (a_pd < b_pd) {
6458 else if (a_year < b_year) {
6465 else if (
f_lt_p(a_nth, b_nth)) {
6523 a_nth =
m_nth(adat);
6524 b_nth =
m_nth(bdat);
6544 a_nth =
m_nth(adat);
6545 b_nth =
m_nth(bdat);
6549 if (a_year == b_year) {
6551 a_mon =
m_mon(adat);
6552 b_mon =
m_mon(bdat);
6553 if (a_mon == b_mon) {
6556 if (a_mday == b_mday)
6622 mk_inspect_flags(
union DateData *x)
6634 mk_inspect_raw(
union DateData *x,
const char *klass)
6644 "(%sth,%dj),+0s,%.0fj; "
6646 klass ? klass :
"?",
6649 x->
s.
year, x->
s.mon, x->
s.mday,
6657 VALUE nth, sf, flags;
6665 "(%sth,%dj,%ds,%sn),%+ds,%.0fj; "
6666 "%dy%dm%dd %dh%dm%ds; %s>",
6667 klass ? klass :
"?",
6672 x->
c.
year, x->
c.mon, x->
c.mday,
6673 x->
c.hour, x->
c.min, x->
c.sec,
6685 d_lite_inspect_raw(
VALUE self)
6701 "#<%s: %s ((%sj,%ds,%sn),%+ds,%.0fj)>",
6702 klass ? klass :
"?",
6737 size_t date_strftime(
char *s,
size_t maxsize,
const char *format,
6740 #define SMALLBUF 100
6754 if (len != 0 || (**buf ==
'\0' &&
errno != ERANGE))
return len;
6755 for (size=1024; ; size*=2) {
6768 if (size >= 1024 * flen) {
6792 #define MILLISECOND_IN_NANOSECONDS 1000000
6823 (int (*)(
void *))
m_mon,
6832 (int (*)(
void *))
m_min,
6833 (int (*)(
void *))
m_sec,
6845 tmx->
dat = (
void *)dat;
6851 const char *default_fmt,
6869 "format should have ASCII compatible encoding");
6874 (*func)(
self, &tmx);
6875 if (memchr(fmt,
'\0', len)) {
6877 const char *
p = fmt, *pe = fmt +
len;
6884 if (buf != buffer) {
6888 for (fmt = p; p < pe && !*
p; ++
p);
6899 if (buf != buffer)
xfree(buf);
7098 (*func)(
self, &tmx);
7101 if (buf != buffer)
xfree(buf);
7222 d_lite_marshal_dump_old(
VALUE self)
7278 VALUE ajd, of, sg, nth, sf;
7287 &nth, &jd, &df, &sf, &rof, &rsg);
7294 "cannot load complex into simple");
7319 "cannot load complex into simple");
7360 VALUE vjd, vh, vmin, vs, vof, vsg, jd, fr, fr2, ret;
7364 rb_scan_args(argc, argv,
"06", &vjd, &vh, &vmin, &vs, &vof, &vsg);
7390 int rh, rmin, rs, rjd, rjd2;
7430 VALUE vy, vd, vh, vmin, vs, vof, vsg, y, fr, fr2, ret;
7431 int d, h,
min, s, rof;
7434 rb_scan_args(argc, argv,
"07", &vy, &vd, &vh, &vmin, &vs, &vof, &vsg);
7463 int ry, rd, rh, rmin, rs, rjd, rjd2, ns;
7508 VALUE vy, vm, vd, vh, vmin, vs, vof, vsg, y, fr, fr2, ret;
7509 int m, d, h,
min, s, rof;
7512 rb_scan_args(argc, argv,
"08", &vy, &vm, &vd, &vh, &vmin, &vs, &vof, &vsg);
7544 int ry, rm, rd, rh, rmin, rs;
7564 int ry, rm, rd, rh, rmin, rs, rjd, rjd2, ns;
7607 VALUE vy, vw, vd, vh, vmin, vs, vof, vsg, y, fr, fr2, ret;
7608 int w, d, h,
min, s, rof;
7611 rb_scan_args(argc, argv,
"08", &vy, &vw, &vd, &vh, &vmin, &vs, &vof, &vsg);
7643 int ry, rw, rd, rh, rmin, rs, rjd, rjd2, ns;
7672 datetime_s_weeknum(
int argc,
VALUE *argv,
VALUE klass)
7674 VALUE vy, vw, vd, vf, vh, vmin, vs, vof, vsg, y, fr, fr2, ret;
7675 int w, d, f, h,
min, s, rof;
7679 &vh, &vmin, &vs, &vof, &vsg);
7714 int ry, rw, rd, rh, rmin, rs, rjd, rjd2, ns;
7741 datetime_s_nth_kday(
int argc,
VALUE *argv,
VALUE klass)
7743 VALUE vy, vm, vn, vk, vh, vmin, vs, vof, vsg, y, fr, fr2, ret;
7744 int m, n, k, h,
min, s, rof;
7748 &vh, &vmin, &vs, &vof, &vsg);
7783 int ry, rm, rn, rk, rh, rmin, rs, rjd, rjd2, ns;
7785 if (!valid_nth_kday_p(y, m, n, k, sg,
7787 &rm, &rn, &rk, &rjd,
7823 VALUE vsg, nth, ret;
7825 #ifdef HAVE_CLOCK_GETTIME
7833 int y, ry, m, d, h,
min, s;
7842 #ifdef HAVE_CLOCK_GETTIME
7843 if (clock_gettime(CLOCK_REALTIME, &ts) == -1)
7855 y = tm.tm_year + 1900;
7863 #ifdef HAVE_STRUCT_TM_TM_GMTOFF
7865 #elif defined(HAVE_VAR_TIMEZONE)
7866 #ifdef HAVE_VAR_ALTZONE
7875 of += (
long)difftime(sec2, sec);
7878 #elif defined(HAVE_TIMEGM)
7883 of = (
long)difftime(sec2, sec);
7892 tm2.tm_isdst = tm.tm_isdst;
7893 sec2 = mktime(&tm2);
7894 of = (
long)difftime(sec, sec2);
7897 #ifdef HAVE_CLOCK_GETTIME
8102 VALUE str, comp, sg;
8247 str =
rb_str_new2(
"Mon, 1 Jan -4712 00:00:00 +0000");
8279 str =
rb_str_new2(
"Mon, 01 Jan -4712 00:00:00 GMT");
8521 "%Y-%m-%dT%H:%M:%S%:z",
set_tmx);
8624 #define f_getlocal(x) rb_funcall(x, rb_intern("getlocal"), 0)
8625 #define f_subsec(x) rb_funcall(x, rb_intern("subsec"), 0)
8626 #define f_utc_offset(x) rb_funcall(x, rb_intern("utc_offset"), 0)
8627 #define f_local3(x,y,m,d) rb_funcall(x, rb_intern("local"), 3, y, m, d)
8628 #define f_utc6(x,y,m,d,h,min,s) rb_funcall(x, rb_intern("utc"), 6,\
8682 VALUE y, sf, nth, ret;
8683 int ry, m, d, h,
min, s, of;
8857 #define MIN_YEAR -4713
8858 #define MAX_YEAR 1000000
8860 #define MAX_JD 366963925
8863 test_civil(
int from,
int to,
double sg)
8867 fprintf(stderr,
"test_civil: %d...%d (%d) - %.0f\n",
8868 from, to, to - from, sg);
8869 for (j = from; j <= to; j++) {
8870 int y, m, d, rj, ns;
8875 fprintf(stderr,
"%d != %d\n", j, rj);
8883 date_s_test_civil(
VALUE klass)
8885 if (!test_civil(MIN_JD, MIN_JD + 366,
GREGORIAN))
8887 if (!test_civil(2305814, 2598007,
GREGORIAN))
8889 if (!test_civil(MAX_JD - 366, MAX_JD,
GREGORIAN))
8892 if (!test_civil(MIN_JD, MIN_JD + 366,
ITALY))
8894 if (!test_civil(2305814, 2598007,
ITALY))
8896 if (!test_civil(MAX_JD - 366, MAX_JD,
ITALY))
8903 test_ordinal(
int from,
int to,
double sg)
8907 fprintf(stderr,
"test_ordinal: %d...%d (%d) - %.0f\n",
8908 from, to, to - from, sg);
8909 for (j = from; j <= to; j++) {
8915 fprintf(stderr,
"%d != %d\n", j, rj);
8923 date_s_test_ordinal(
VALUE klass)
8925 if (!test_ordinal(MIN_JD, MIN_JD + 366,
GREGORIAN))
8927 if (!test_ordinal(2305814, 2598007,
GREGORIAN))
8929 if (!test_ordinal(MAX_JD - 366, MAX_JD,
GREGORIAN))
8932 if (!test_ordinal(MIN_JD, MIN_JD + 366,
ITALY))
8934 if (!test_ordinal(2305814, 2598007,
ITALY))
8936 if (!test_ordinal(MAX_JD - 366, MAX_JD,
ITALY))
8943 test_commercial(
int from,
int to,
double sg)
8947 fprintf(stderr,
"test_commercial: %d...%d (%d) - %.0f\n",
8948 from, to, to - from, sg);
8949 for (j = from; j <= to; j++) {
8950 int y, w, d, rj, ns;
8955 fprintf(stderr,
"%d != %d\n", j, rj);
8963 date_s_test_commercial(
VALUE klass)
8965 if (!test_commercial(MIN_JD, MIN_JD + 366,
GREGORIAN))
8967 if (!test_commercial(2305814, 2598007,
GREGORIAN))
8969 if (!test_commercial(MAX_JD - 366, MAX_JD,
GREGORIAN))
8972 if (!test_commercial(MIN_JD, MIN_JD + 366,
ITALY))
8974 if (!test_commercial(2305814, 2598007,
ITALY))
8976 if (!test_commercial(MAX_JD - 366, MAX_JD,
ITALY))
8983 test_weeknum(
int from,
int to,
int f,
double sg)
8987 fprintf(stderr,
"test_weeknum: %d...%d (%d) - %.0f\n",
8988 from, to, to - from, sg);
8989 for (j = from; j <= to; j++) {
8990 int y, w, d, rj, ns;
8995 fprintf(stderr,
"%d != %d\n", j, rj);
9003 date_s_test_weeknum(
VALUE klass)
9007 for (f = 0; f <= 1; f++) {
9008 if (!test_weeknum(MIN_JD, MIN_JD + 366, f,
GREGORIAN))
9010 if (!test_weeknum(2305814, 2598007, f,
GREGORIAN))
9012 if (!test_weeknum(MAX_JD - 366, MAX_JD, f,
GREGORIAN))
9015 if (!test_weeknum(MIN_JD, MIN_JD + 366, f,
ITALY))
9017 if (!test_weeknum(2305814, 2598007, f,
ITALY))
9019 if (!test_weeknum(MAX_JD - 366, MAX_JD, f,
ITALY))
9027 test_nth_kday(
int from,
int to,
double sg)
9031 fprintf(stderr,
"test_nth_kday: %d...%d (%d) - %.0f\n",
9032 from, to, to - from, sg);
9033 for (j = from; j <= to; j++) {
9034 int y, m, n, k, rj, ns;
9036 c_jd_to_nth_kday(j, sg, &y, &m, &n, &k);
9037 c_nth_kday_to_jd(y, m, n, k, sg, &rj, &ns);
9039 fprintf(stderr,
"%d != %d\n", j, rj);
9047 date_s_test_nth_kday(
VALUE klass)
9049 if (!test_nth_kday(MIN_JD, MIN_JD + 366,
GREGORIAN))
9051 if (!test_nth_kday(2305814, 2598007,
GREGORIAN))
9053 if (!test_nth_kday(MAX_JD - 366, MAX_JD,
GREGORIAN))
9056 if (!test_nth_kday(MIN_JD, MIN_JD + 366,
ITALY))
9058 if (!test_nth_kday(2305814, 2598007,
ITALY))
9060 if (!test_nth_kday(MAX_JD - 366, MAX_JD,
ITALY))
9081 if (!test_unit_v2v(
INT2FIX(0), conv1, conv2))
9083 if (!test_unit_v2v(
INT2FIX(1), conv1, conv2))
9085 if (!test_unit_v2v(
INT2FIX(2), conv1, conv2))
9087 if (!test_unit_v2v(
INT2FIX(3), conv1, conv2))
9089 if (!test_unit_v2v(
INT2FIX(11), conv1, conv2))
9091 if (!test_unit_v2v(
INT2FIX(65535), conv1, conv2))
9093 if (!test_unit_v2v(
INT2FIX(1073741823), conv1, conv2))
9095 if (!test_unit_v2v(
INT2NUM(1073741824), conv1, conv2))
9112 if (!test_unit_v2v_iter2(conv1, conv2))
9114 if (!test_unit_v2v_iter2(conv2, conv1))
9120 date_s_test_unit_conv(
VALUE klass)
9124 if (!test_unit_v2v_iter(ms_to_sec,
sec_to_ms))
9126 if (!test_unit_v2v_iter(
ns_to_day, day_to_ns))
9134 date_s_test_all(
VALUE klass)
9136 if (date_s_test_civil(klass) ==
Qfalse)
9138 if (date_s_test_ordinal(klass) ==
Qfalse)
9140 if (date_s_test_commercial(klass) ==
Qfalse)
9142 if (date_s_test_weeknum(klass) ==
Qfalse)
9144 if (date_s_test_nth_kday(klass) ==
Qfalse)
9146 if (date_s_test_unit_conv(klass) ==
Qfalse)
9154 "January",
"February",
"March",
9155 "April",
"May",
"June",
9156 "July",
"August",
"September",
9157 "October",
"November",
"December"
9162 "Jan",
"Feb",
"Mar",
"Apr",
9163 "May",
"Jun",
"Jul",
"Aug",
9164 "Sep",
"Oct",
"Nov",
"Dec"
9168 "Sunday",
"Monday",
"Tuesday",
"Wednesday",
9169 "Thursday",
"Friday",
"Saturday"
9173 "Sun",
"Mon",
"Tue",
"Wed",
9184 for (i = 0; i <
len; i++) {
9203 #define rb_intern(str) rb_intern_const(str)
9205 assert(fprintf(stderr,
"assert() is now active\n"));
9214 #if (LONG_MAX / DAY_IN_SECONDS) > SECOND_IN_NANOSECONDS
9217 #elif defined HAVE_LONG_LONG
9219 SECOND_IN_NANOSECONDS);
9222 INT2FIX(SECOND_IN_NANOSECONDS));
9479 #define de_define_private_method rb_define_private_method
9481 date_s__valid_jd_p, -1);
9482 de_define_private_method(
CLASS_OF(
cDate),
"_valid_ordinal?",
9483 date_s__valid_ordinal_p, -1);
9485 date_s__valid_civil_p, -1);
9487 date_s__valid_civil_p, -1);
9488 de_define_private_method(
CLASS_OF(
cDate),
"_valid_commercial?",
9489 date_s__valid_commercial_p, -1);
9490 de_define_private_method(
CLASS_OF(
cDate),
"_valid_weeknum?",
9491 date_s__valid_weeknum_p, -1);
9492 de_define_private_method(
CLASS_OF(
cDate),
"_valid_nth_kday?",
9493 date_s__valid_nth_kday_p, -1);
9506 date_s_valid_weeknum_p, -1);
9507 de_define_private_method(
CLASS_OF(
cDate),
"valid_nth_kday?",
9508 date_s_valid_nth_kday_p, -1);
9510 date_s_zone_to_diff, 1);
9520 #define de_define_singleton_method rb_define_singleton_method
9521 #define de_define_alias rb_define_alias
9522 de_define_singleton_method(
cDate,
"new!", date_s_new_bang, -1);
9533 de_define_singleton_method(
cDate,
"weeknum", date_s_weeknum, -1);
9534 de_define_singleton_method(
cDate,
"nth_kday", date_s_nth_kday, -1);
9558 #define de_define_method rb_define_method
9559 de_define_method(
cDate,
"initialize", d_lite_initialize, -1);
9564 de_define_method(
cDate,
"fill", d_lite_fill, 0);
9586 de_define_private_method(
cDate,
"wnum0", d_lite_wnum0, 0);
9587 de_define_private_method(
cDate,
"wnum1", d_lite_wnum1, 0);
9601 de_define_method(
cDate,
"nth_kday?", d_lite_nth_kday_p, 2);
9654 de_define_method(
cDate,
"inspect_raw", d_lite_inspect_raw, 0);
9671 de_define_method(
cDate,
"marshal_dump_old", d_lite_marshal_dump_old, 0);
9688 de_define_singleton_method(
cDateTime,
"weeknum",
9689 datetime_s_weeknum, -1);
9690 de_define_singleton_method(
cDateTime,
"nth_kday",
9691 datetime_s_nth_kday, -1);
9718 #define f_public(m,s) rb_funcall(m, rb_intern("public"), 1,\
9719 ID2SYM(rb_intern(s)))
9758 de_define_singleton_method(
cDate,
"test_civil", date_s_test_civil, 0);
9759 de_define_singleton_method(
cDate,
"test_ordinal", date_s_test_ordinal, 0);
9760 de_define_singleton_method(
cDate,
"test_commercial",
9761 date_s_test_commercial, 0);
9762 de_define_singleton_method(
cDate,
"test_weeknum", date_s_test_weeknum, 0);
9763 de_define_singleton_method(
cDate,
"test_nth_kday", date_s_test_nth_kday, 0);
9764 de_define_singleton_method(
cDate,
"test_unit_conv",
9765 date_s_test_unit_conv, 0);
9766 de_define_singleton_method(
cDate,
"test_all", date_s_test_all, 0);