summaryrefslogtreecommitdiff
path: root/ext
diff options
context:
space:
mode:
authortadf <tadf@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2011-06-04 08:02:37 +0000
committertadf <tadf@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2011-06-04 08:02:37 +0000
commit6dc8503fa5c09aaff653c243bb1bd36f16a38a84 (patch)
tree9a91659654310575786d5b9c08e444459b79c390 /ext
parent83ef8ee73e80e1b34ef95db844b8a0958f24eb39 (diff)
* ext/date/date_core.c (d_lite_inspect): changed the format.
* ext/date/date_core.c: refactoring and fixing some bugs. git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@31920 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
Diffstat (limited to 'ext')
-rw-r--r--ext/date/date_core.c1915
1 files changed, 1108 insertions, 807 deletions
diff --git a/ext/date/date_core.c b/ext/date/date_core.c
index aafc6aac8a..763e059550 100644
--- a/ext/date/date_core.c
+++ b/ext/date/date_core.c
@@ -14,131 +14,13 @@
#include RUBY_EXTCONF_H
#endif
-#define USE_DPK
+#define USE_PACK
static ID id_cmp, id_le_p, id_ge_p, id_eqeq_p;
static VALUE cDate, cDateTime;
static VALUE half_days_in_day, unix_epoch_in_ajd, day_in_nanoseconds;
static double positive_inf, negative_inf;
-#define HAVE_JD (1 << 0)
-#define HAVE_DF (1 << 1)
-#define HAVE_CIVIL (1 << 2)
-#define HAVE_TIME (1 << 3)
-#define COMPLEX_DAT (1 << 7)
-
-#define have_jd_p(x) ((x)->flags & HAVE_JD)
-#define have_df_p(x) ((x)->flags & HAVE_DF)
-#define have_civil_p(x) ((x)->flags & HAVE_CIVIL)
-#define have_time_p(x) ((x)->flags & HAVE_TIME)
-#define complex_dat_p(x) ((x)->flags & COMPLEX_DAT)
-#define simple_dat_p(x) (!complex_dat_p(x))
-
-#define ITALY 2299161
-#define ENGLAND 2361222
-#define JULIAN positive_inf
-#define GREGORIAN negative_inf
-#define DEFAULT_SG ITALY
-
-#define UNIX_EPOCH_IN_AJD unix_epoch_in_ajd /* 1970-01-01 */
-#define UNIX_EPOCH_IN_CJD INT2FIX(2440588)
-
-#define MINUTE_IN_SECONDS 60
-#define HOUR_IN_SECONDS 3600
-#define DAY_IN_SECONDS 86400
-#define SECOND_IN_NANOSECONDS 1000000000
-
-#define JC_PERIOD0 1461 /* 365.25 * 4 */
-#define GC_PERIOD0 146097 /* 365.2425 * 400 */
-#define CM_PERIOD0 71149239 /* (lcm 7 1461 146097) */
-#define CM_PERIOD (0xfffffff / CM_PERIOD0 * CM_PERIOD0)
-#define CM_PERIOD_JCY (CM_PERIOD / JC_PERIOD0 * 4)
-#define CM_PERIOD_GCY (CM_PERIOD / GC_PERIOD0 * 400)
-
-#ifdef USE_PACK
-#define SEC_WIDTH 6
-#define MIN_WIDTH 6
-#define HOUR_WIDTH 5
-#define MDAY_WIDTH 5
-#define MON_WIDTH 4
-
-#define SEC_SHIFT 0
-#define MIN_SHIFT SEC_WIDTH
-#define HOUR_SHIFT (MIN_WIDTH + SEC_WIDTH)
-#define MDAY_SHIFT (HOUR_WIDTH + MIN_WIDTH + SEC_WIDTH)
-#define MON_SHIFT (MDAY_WIDTH + HOUR_WIDTH + MIN_WIDTH + SEC_WIDTH)
-
-#define PK_MASK(x) ((1 << (x)) - 1)
-
-#define EX_SEC(x) (((x) >> SEC_SHIFT) & PK_MASK(SEC_WIDTH))
-#define EX_MIN(x) (((x) >> MIN_SHIFT) & PK_MASK(MIN_WIDTH))
-#define EX_HOUR(x) (((x) >> HOUR_SHIFT) & PK_MASK(HOUR_WIDTH))
-#define EX_MDAY(x) (((x) >> MDAY_SHIFT) & PK_MASK(MDAY_WIDTH))
-#define EX_MON(x) (((x) >> MON_SHIFT) & PK_MASK(MON_WIDTH))
-
-#define PACK5(m,d,h,min,s) \
- (((m) << MON_SHIFT) | ((d) << MDAY_SHIFT) |\
- ((h) << HOUR_SHIFT) | ((min) << MIN_SHIFT) | ((s) << SEC_SHIFT))
-
-#define PACK2(m,d) \
- (((m) << MON_SHIFT) | ((d) << MDAY_SHIFT))
-#endif
-
-struct SimpleDateData
-{
- unsigned flags;
- VALUE nth; /* not always canonicalized */
- int jd; /* as utc */
- double sg; /* -oo, 2299161..2451910 or +oo */
- /* decoded as utc=local */
- int year; /* truncated */
-#ifndef USE_PACK
- int mon;
- int mday;
-#else
- /* packed civil */
- unsigned pd;
-#endif
-};
-
-struct ComplexDateData
-{
- unsigned flags;
- VALUE nth; /* not always canonicalized */
- int jd; /* as utc */
- int df; /* as utc, in secs */
- VALUE sf; /* in nano secs */
- int of; /* in secs */
- double sg; /* -oo, 2299161..2451910 or +oo */
- /* decoded as local */
- int year; /* truncated */
-#ifndef USE_PACK
- int mon;
- int mday;
- int hour;
- int min;
- int sec;
-#else
- /* packed civil */
- unsigned pd;
-#endif
-};
-
-union DateData {
- unsigned flags;
- struct SimpleDateData s;
- struct ComplexDateData c;
-};
-
-#define get_d1(x)\
- union DateData *dat;\
- Data_Get_Struct(x, union DateData, dat);
-
-#define get_d2(x,y)\
- union DateData *adat, *bdat;\
- Data_Get_Struct(x, union DateData, adat);\
- Data_Get_Struct(y, union DateData, bdat);
-
#define f_boolcast(x) ((x) ? Qtrue : Qfalse)
#define f_abs(x) rb_funcall(x, rb_intern("abs"), 0)
@@ -218,8 +100,6 @@ f_eqeq_p(VALUE x, VALUE y)
return rb_funcall(x, rb_intern("=="), 1, y);
}
-#define f_equal_p(x,y) rb_funcall(x, rb_intern("==="), 1, y)
-
inline static VALUE
f_zero_p(VALUE x)
{
@@ -231,7 +111,6 @@ f_zero_p(VALUE x)
case T_RATIONAL:
{
VALUE num = RRATIONAL(x)->num;
-
return f_boolcast(FIXNUM_P(num) && FIX2LONG(num) == 0);
}
}
@@ -268,7 +147,271 @@ f_negative_p(VALUE x)
#define DIV(n,d) ((n)<0 ? NDIV((n),(d)) : (n)/(d))
#define MOD(n,d) ((n)<0 ? NMOD((n),(d)) : (n)%(d))
-/* light base */
+#define HAVE_JD (1 << 0)
+#define HAVE_DF (1 << 1)
+#define HAVE_CIVIL (1 << 2)
+#define HAVE_TIME (1 << 3)
+#define COMPLEX_DAT (1 << 7)
+
+#define have_jd_p(x) ((x)->flags & HAVE_JD)
+#define have_df_p(x) ((x)->flags & HAVE_DF)
+#define have_civil_p(x) ((x)->flags & HAVE_CIVIL)
+#define have_time_p(x) ((x)->flags & HAVE_TIME)
+#define complex_dat_p(x) ((x)->flags & COMPLEX_DAT)
+#define simple_dat_p(x) (!complex_dat_p(x))
+
+#define ITALY 2299161
+#define ENGLAND 2361222
+#define JULIAN positive_inf
+#define GREGORIAN negative_inf
+#define DEFAULT_SG ITALY
+
+#define UNIX_EPOCH_IN_AJD unix_epoch_in_ajd /* 1970-01-01 */
+#define UNIX_EPOCH_IN_CJD INT2FIX(2440588)
+
+#define MINUTE_IN_SECONDS 60
+#define HOUR_IN_SECONDS 3600
+#define DAY_IN_SECONDS 86400
+#define SECOND_IN_NANOSECONDS 1000000000
+
+#define JC_PERIOD0 1461 /* 365.25 * 4 */
+#define GC_PERIOD0 146097 /* 365.2425 * 400 */
+#define CM_PERIOD0 71149239 /* (lcm 7 1461 146097) */
+#define CM_PERIOD (0xfffffff / CM_PERIOD0 * CM_PERIOD0)
+#define CM_PERIOD_JCY (CM_PERIOD / JC_PERIOD0 * 4)
+#define CM_PERIOD_GCY (CM_PERIOD / GC_PERIOD0 * 400)
+
+#define REFORM_BEGIN_YEAR 1582
+#define REFORM_END_YEAR 1930
+#define REFORM_BEGIN_JD 2298874 /* ns 1582-01-01 */
+#define REFORM_END_JD 2426355 /* os 1930-12-31 */
+
+#ifdef USE_PACK
+#define SEC_WIDTH 6
+#define MIN_WIDTH 6
+#define HOUR_WIDTH 5
+#define MDAY_WIDTH 5
+#define MON_WIDTH 4
+
+#define SEC_SHIFT 0
+#define MIN_SHIFT SEC_WIDTH
+#define HOUR_SHIFT (MIN_WIDTH + SEC_WIDTH)
+#define MDAY_SHIFT (HOUR_WIDTH + MIN_WIDTH + SEC_WIDTH)
+#define MON_SHIFT (MDAY_WIDTH + HOUR_WIDTH + MIN_WIDTH + SEC_WIDTH)
+
+#define PK_MASK(x) ((1 << (x)) - 1)
+
+#define EX_SEC(x) (((x) >> SEC_SHIFT) & PK_MASK(SEC_WIDTH))
+#define EX_MIN(x) (((x) >> MIN_SHIFT) & PK_MASK(MIN_WIDTH))
+#define EX_HOUR(x) (((x) >> HOUR_SHIFT) & PK_MASK(HOUR_WIDTH))
+#define EX_MDAY(x) (((x) >> MDAY_SHIFT) & PK_MASK(MDAY_WIDTH))
+#define EX_MON(x) (((x) >> MON_SHIFT) & PK_MASK(MON_WIDTH))
+
+#define PACK5(m,d,h,min,s) \
+ (((m) << MON_SHIFT) | ((d) << MDAY_SHIFT) |\
+ ((h) << HOUR_SHIFT) | ((min) << MIN_SHIFT) | ((s) << SEC_SHIFT))
+
+#define PACK2(m,d) \
+ (((m) << MON_SHIFT) | ((d) << MDAY_SHIFT))
+#endif
+
+#ifdef HAVE_FLOAT_H
+#include <float.h>
+#endif
+
+#if defined(FLT_RADIX) && defined(FLT_MANT_DIG)
+#if FLT_RADIX == 2 && FLT_MANT_DIG > 22
+#define USE_FLOAT
+#define sg_cast float
+#else
+#define sg_cast double
+#endif
+#endif
+
+struct SimpleDateData
+{
+ unsigned flags;
+ VALUE nth; /* not always canonicalized */
+ int jd; /* as utc */
+#ifndef USE_FLOAT
+ double sg; /* 2298874..2426355 or -/+oo */
+#else
+ float sg; /* at most 22 bits */
+#endif
+ /* decoded as utc=local */
+ int year; /* truncated */
+#ifndef USE_PACK
+ int mon;
+ int mday;
+#else
+ /* packed civil */
+ unsigned pc;
+#endif
+};
+
+struct ComplexDateData
+{
+ unsigned flags;
+ VALUE nth; /* not always canonicalized */
+ int jd; /* as utc */
+ int df; /* as utc, in secs */
+ VALUE sf; /* in nano secs */
+ int of; /* in secs */
+#ifndef USE_FLOAT
+ double sg; /* 2298874..2426355 or -/+oo */
+#else
+ float sg; /* at most 22 bits */
+#endif
+ /* decoded as local */
+ int year; /* truncated */
+#ifndef USE_PACK
+ int mon;
+ int mday;
+ int hour;
+ int min;
+ int sec;
+#else
+ /* packed civil */
+ unsigned pc;
+#endif
+};
+
+union DateData {
+ unsigned flags;
+ struct SimpleDateData s;
+ struct ComplexDateData c;
+};
+
+#define get_d1(x)\
+ union DateData *dat;\
+ Data_Get_Struct(x, union DateData, dat);
+
+#define get_d1a(x)\
+ union DateData *adat;\
+ Data_Get_Struct(x, union DateData, adat);
+
+#define get_d1b(x)\
+ union DateData *bdat;\
+ Data_Get_Struct(x, union DateData, bdat);
+
+#define get_d2(x,y)\
+ union DateData *adat, *bdat;\
+ Data_Get_Struct(x, union DateData, adat);\
+ Data_Get_Struct(y, union DateData, bdat);
+
+#ifndef USE_PACK
+#define set_to_simple(x, _nth, _jd ,_sg, _year, _mon, _mday, _flags) \
+{\
+ (x)->nth = _nth;\
+ (x)->jd = _jd;\
+ (x)->sg = (sg_cast)(_sg);\
+ (x)->year = _year;\
+ (x)->mon = _mon;\
+ (x)->mday = _mday;\
+ (x)->flags = _flags;\
+}
+#else
+#define set_to_simple(x, _nth, _jd ,_sg, _year, _mon, _mday, _flags) \
+{\
+ (x)->nth = _nth;\
+ (x)->jd = _jd;\
+ (x)->sg = (sg_cast)(_sg);\
+ (x)->year = _year;\
+ (x)->pc = PACK2(_mon, _mday);\
+ (x)->flags = _flags;\
+}
+#endif
+
+#ifndef USE_PACK
+#define set_to_complex(x, _nth, _jd ,_df, _sf, _of, _sg,\
+_year, _mon, _mday, _hour, _min, _sec, _flags) \
+{\
+ (x)->nth = _nth;\
+ (x)->jd = _jd;\
+ (x)->df = _df;\
+ (x)->sf = _sf;\
+ (x)->of = _of;\
+ (x)->sg = (sg_cast)(_sg);\
+ (x)->year = _year;\
+ (x)->mon = _mon;\
+ (x)->mday = _mday;\
+ (x)->hour = _hour;\
+ (x)->min = _min;\
+ (x)->sec = _sec;\
+ (x)->flags = _flags;\
+}
+#else
+#define set_to_complex(x, _nth, _jd ,_df, _sf, _of, _sg,\
+_year, _mon, _mday, _hour, _min, _sec, _flags) \
+{\
+ (x)->nth = _nth;\
+ (x)->jd = _jd;\
+ (x)->df = _df;\
+ (x)->sf = _sf;\
+ (x)->of = _of;\
+ (x)->sg = (sg_cast)(_sg);\
+ (x)->year = _year;\
+ (x)->pc = PACK5(_mon, _mday, _hour, _min, _sec);\
+ (x)->flags = _flags;\
+}
+#endif
+
+#ifndef USE_PACK
+#define copy_simple_to_complex(x, y) \
+{\
+ (x)->nth = (y)->nth;\
+ (x)->jd = (y)->jd;\
+ (x)->df = 0;\
+ (x)->sf = INT2FIX(0);\
+ (x)->of = 0;\
+ (x)->sg = (sg_cast)((y)->sg);\
+ (x)->year = (y)->year;\
+ (x)->mon = (y)->mon;\
+ (x)->mday = (y)->mday;\
+ (x)->hour = 0;\
+ (x)->min = 0;\
+ (x)->sec = 0;\
+ (x)->flags = (y)->flags;\
+}
+#else
+#define copy_simple_to_complex(x, y) \
+{\
+ (x)->nth = (y)->nth;\
+ (x)->jd = (y)->jd;\
+ (x)->df = 0;\
+ (x)->sf = INT2FIX(0);\
+ (x)->of = 0;\
+ (x)->sg = (sg_cast)((y)->sg);\
+ (x)->year = (y)->year;\
+ (x)->pc = PACK5(EX_MON((y)->pc), EX_MDAY((y)->pc), 0, 0, 0);\
+ (x)->flags = (y)->flags;\
+}
+#endif
+
+#ifndef USE_PACK
+#define copy_complex_to_simple(x, y) \
+{\
+ (x)->nth = (y)->nth;\
+ (x)->jd = (y)->jd;\
+ (x)->sg = (sg_cast)((y)->sg);\
+ (x)->year = (y)->year;\
+ (x)->mon = (y)->mon;\
+ (x)->mday = (y)->mday;\
+ (x)->flags = (y)->flags;\
+}
+#else
+#define copy_complex_to_simple(x, y) \
+{\
+ (x)->nth = (y)->nth;\
+ (x)->jd = (y)->jd;\
+ (x)->sg = (sg_cast)((y)->sg);\
+ (x)->year = (y)->year;\
+ (x)->pc = PACK5(EX_MON((y)->pc), EX_MDAY((y)->pc), 0, 0, 0);\
+ (x)->flags = (y)->flags;\
+}
+#endif
+
+/* base */
static int c_valid_civil_p(int, int, int, double,
int *, int *, int *, int *);
@@ -518,33 +661,67 @@ static const int monthtab[2][13] = {
};
inline static int
-c_leap_p(int y)
+c_julian_leap_p(int y)
+{
+ return MOD(y, 4) == 0;
+}
+
+inline static int
+c_gregorian_leap_p(int y)
{
- return (MOD(y, 4) == 0 && y % 100 != 0) || (MOD(y, 400) == 0);
+ return MOD(y, 4) == 0 && y % 100 != 0 || MOD(y, 400) == 0;
}
static int
-c_last_day_of_month(int y, int m)
+c_julian_last_day_of_month(int y, int m)
{
- return monthtab[c_leap_p(y) ? 1 : 0][m];
+ assert(m >= 1 && m <= 12);
+ return monthtab[c_julian_leap_p(y) ? 1 : 0][m];
}
static int
-c_valid_gregorian_p(int y, int m, int d, int *rm, int *rd)
+c_gregorian_last_day_of_month(int y, int m)
+{
+ assert(m >= 1 && m <= 12);
+ return monthtab[c_gregorian_leap_p(y) ? 1 : 0][m];
+}
+
+static int
+c_valid_julian_p(int y, int m, int d, int *rm, int *rd)
{
int last;
if (m < 0)
m += 13;
- last = c_last_day_of_month(y, m);
+ if (m < 0 || m > 12)
+ return 0;
+ last = c_julian_last_day_of_month(y, m);
if (d < 0)
d = last + d + 1;
-
+ if (d < 1 || d > last)
+ return 0;
*rm = m;
*rd = d;
+ return 1;
+}
+
+static int
+c_valid_gregorian_p(int y, int m, int d, int *rm, int *rd)
+{
+ int last;
- return !(m < 0 || m > 12 ||
- d < 1 || d > last);
+ if (m < 0)
+ m += 13;
+ if (m < 0 || m > 12)
+ return 0;
+ last = c_gregorian_last_day_of_month(y, m);
+ if (d < 0)
+ d = last + d + 1;
+ if (d < 1 || d > last)
+ return 0;
+ *rm = m;
+ *rd = d;
+ return 1;
}
static int
@@ -666,15 +843,16 @@ c_valid_time_p(int h, int min, int s, int *rh, int *rmin, int *rs)
(h == 24 && (min > 0 || s > 0)));
}
-static int
+inline static int
c_valid_start_p(double sg)
{
if (!isinf(sg)) {
- if (sg < ITALY)
+ if (sg < REFORM_BEGIN_JD)
return 0;
- if (sg > 2451910)
+ if (sg > REFORM_END_JD)
return 0;
- }
+ } else if (isnan(sg))
+ return 0;
return 1;
}
@@ -728,13 +906,22 @@ time_to_df(int h, int min, int s)
return h * HOUR_IN_SECONDS + min * MINUTE_IN_SECONDS + s;
}
+inline static void
+df_to_time(int df, int *h, int *min, int *s)
+{
+ *h = df / HOUR_IN_SECONDS;
+ df %= HOUR_IN_SECONDS;
+ *min = df / MINUTE_IN_SECONDS;
+ *s = df % MINUTE_IN_SECONDS;
+}
+
static VALUE
sec_to_day(VALUE s)
{
return f_quo(s, INT2FIX(DAY_IN_SECONDS));
}
-static VALUE
+inline static VALUE
isec_to_day(int s)
{
return sec_to_day(INT2FIX(s));
@@ -753,16 +940,31 @@ ns_to_sec(VALUE n)
}
#ifndef NDEBUG
-static VALUE
+inline static VALUE
ins_to_day(int n)
{
return ns_to_day(INT2FIX(n));
}
#endif
+static int
+safe_mul_p(VALUE x, long m)
+{
+ long ix;
+
+ if (!FIXNUM_P(x))
+ return 0;
+ ix = FIX2LONG(x);
+ if (ix >= (FIXNUM_MAX / m))
+ return 0;
+ return 1;
+}
+
static VALUE
day_to_sec(VALUE d)
{
+ if (safe_mul_p(d, DAY_IN_SECONDS))
+ return LONG2FIX(FIX2LONG(d) * DAY_IN_SECONDS);
return f_mul(d, INT2FIX(DAY_IN_SECONDS));
}
@@ -777,6 +979,8 @@ day_to_ns(VALUE d)
static VALUE
sec_to_ns(VALUE s)
{
+ if (safe_mul_p(s, SECOND_IN_NANOSECONDS))
+ return LONG2FIX(FIX2LONG(s) * SECOND_IN_NANOSECONDS);
return f_mul(s, INT2FIX(SECOND_IN_NANOSECONDS));
}
@@ -844,6 +1048,15 @@ c_sg(union DateData *x)
return negative_inf;
}
+inline static double
+x_sg(union DateData *x)
+{
+ if (simple_dat_p(x))
+ return s_sg(x);
+ else
+ return c_sg(x);
+}
+
inline static void
get_s_jd(union DateData *x)
{
@@ -855,7 +1068,7 @@ get_s_jd(union DateData *x)
#ifndef USE_PACK
c_civil_to_jd(x->s.year, x->s.mon, x->s.mday, s_sg(x), &jd, &ns);
#else
- c_civil_to_jd(x->s.year, EX_MON(x->s.pd), EX_MDAY(x->s.pd),
+ c_civil_to_jd(x->s.year, EX_MON(x->s.pc), EX_MDAY(x->s.pc),
s_sg(x), &jd, &ns);
#endif
x->s.jd = jd;
@@ -877,7 +1090,7 @@ get_s_civil(union DateData *x)
x->s.mon = m;
x->s.mday = d;
#else
- x->s.pd = PACK2(m, d);
+ x->s.pc = PACK2(m, d);
#endif
x->s.flags |= HAVE_CIVIL;
}
@@ -893,9 +1106,9 @@ get_c_df(union DateData *x)
x->c.df = df_local_to_utc(time_to_df(x->c.hour, x->c.min, x->c.sec),
x->c.of);
#else
- x->c.df = df_local_to_utc(time_to_df(EX_HOUR(x->c.pd),
- EX_MIN(x->c.pd),
- EX_SEC(x->c.pd)),
+ x->c.df = df_local_to_utc(time_to_df(EX_HOUR(x->c.pc),
+ EX_MIN(x->c.pc),
+ EX_SEC(x->c.pc)),
x->c.of);
#endif
x->c.flags |= HAVE_DF;
@@ -911,23 +1124,17 @@ get_c_time(union DateData *x)
int r;
assert(have_df_p(x));
r = df_utc_to_local(x->c.df, x->c.of);
- x->c.hour = r / HOUR_IN_SECONDS;
- r %= HOUR_IN_SECONDS;
- x->c.min = r / MINUTE_IN_SECONDS;
- x->c.sec = r % MINUTE_IN_SECONDS;
+ df_to_time(r, &x->c.hour, &x->c.min, &x->c.sec);
x->c.flags |= HAVE_TIME;
#else
int r, m, d, h, min, s;
assert(have_df_p(x));
+ m = EX_MON(x->c.pc);
+ d = EX_MDAY(x->c.pc);
r = df_utc_to_local(x->c.df, x->c.of);
- m = EX_MON(x->c.pd);
- d = EX_MDAY(x->c.pd);
- h = r / HOUR_IN_SECONDS;
- r %= HOUR_IN_SECONDS;
- min = r / MINUTE_IN_SECONDS;
- s = r % MINUTE_IN_SECONDS;
- x->c.pd = PACK5(m, d, h, min, s);
+ df_to_time(r, &h, &min, &s);
+ x->c.pc = PACK5(m, d, h, min, s);
x->c.flags |= HAVE_TIME;
#endif
}
@@ -944,7 +1151,7 @@ get_c_jd(union DateData *x)
#ifndef USE_PACK
c_civil_to_jd(x->c.year, x->c.mon, x->c.mday, c_sg(x), &jd, &ns);
#else
- c_civil_to_jd(x->c.year, EX_MON(x->c.pd), EX_MDAY(x->c.pd),
+ c_civil_to_jd(x->c.year, EX_MON(x->c.pc), EX_MDAY(x->c.pc),
c_sg(x), &jd, &ns);
#endif
@@ -955,9 +1162,9 @@ get_c_jd(union DateData *x)
x->c.of);
#else
x->c.jd = jd_local_to_utc(jd,
- time_to_df(EX_HOUR(x->c.pd),
- EX_MIN(x->c.pd),
- EX_SEC(x->c.pd)),
+ time_to_df(EX_HOUR(x->c.pc),
+ EX_MIN(x->c.pc),
+ EX_SEC(x->c.pc)),
x->c.of);
#endif
x->c.flags |= HAVE_JD;
@@ -984,10 +1191,10 @@ get_c_civil(union DateData *x)
x->c.mon = m;
x->c.mday = d;
#else
- h = EX_HOUR(x->c.pd);
- min = EX_MIN(x->c.pd);
- s = EX_SEC(x->c.pd);
- x->c.pd = PACK5(m, d, h, min, s);
+ h = EX_HOUR(x->c.pc);
+ min = EX_MIN(x->c.pc);
+ s = EX_SEC(x->c.pc);
+ x->c.pc = PACK5(m, d, h, min, s);
#endif
x->c.flags |= HAVE_CIVIL;
}
@@ -1020,6 +1227,21 @@ decode_year(VALUE y, double style,
period = (style < 0) ?
CM_PERIOD_GCY :
CM_PERIOD_JCY;
+ if (FIXNUM_P(y)) {
+ long iy, it, inth;
+
+ iy = FIX2LONG(y);
+ if (iy >= (FIXNUM_MAX - 4712))
+ goto big;
+ it = iy + 4712; /* shift */
+ inth = DIV(it, ((long)period));
+ *nth = LONG2FIX(inth);
+ if (inth)
+ it = MOD(it, ((long)period));
+ *ry = (int)it - 4712; /* unshift */
+ return;
+ }
+ big:
t = f_add(y, INT2FIX(4712)); /* shift */
*nth = f_idiv(t, INT2FIX(period));
if (f_nonzero_p(*nth))
@@ -1067,37 +1289,39 @@ encode_jd(VALUE nth, int jd, VALUE *rjd)
*rjd = f_add(f_mul(INT2FIX(CM_PERIOD), nth), INT2FIX(jd));
}
-static double
+inline static double
style_p(VALUE y, double sg)
{
double style = 0;
if (isinf(sg))
- style = (sg < 0) ? negative_inf : positive_inf;
+ style = sg;
else if (!FIXNUM_P(y))
- style = (f_positive_p(y)) ? negative_inf : positive_inf;
+ style = f_positive_p(y) ? negative_inf : positive_inf;
else {
- if (f_lt_p(y, INT2FIX(1582)))
+ long iy = FIX2LONG(y);
+
+ assert(FIXNUM_P(y));
+ if (iy < REFORM_BEGIN_YEAR)
style = positive_inf;
- else if (f_gt_p(y, INT2FIX(2001)))
+ else if (iy > REFORM_END_YEAR)
style = negative_inf;
}
return style;
}
-static VALUE
+inline static VALUE
m_nth(union DateData *x)
{
- if (simple_dat_p(x)) {
+ if (simple_dat_p(x))
return x->s.nth;
- }
else {
get_c_civil(x);
return x->c.nth;
}
}
-static int
+inline static int
m_jd(union DateData *x)
{
if (simple_dat_p(x)) {
@@ -1150,7 +1374,7 @@ m_real_local_jd(union DateData *x)
return rjd;
}
-static int
+inline static int
m_df(union DateData *x)
{
if (simple_dat_p(x))
@@ -1188,7 +1412,7 @@ m_local_df_in_day(union DateData *x)
}
#endif
-static VALUE
+inline static VALUE
m_sf(union DateData *x)
{
if (simple_dat_p(x))
@@ -1235,14 +1459,37 @@ m_ajd(union DateData *x)
VALUE r, sf;
int df;
+ if (simple_dat_p(x))
+ return rb_rational_new2(f_sub(f_mul(m_real_jd(x),
+ INT2FIX(2)),
+ INT2FIX(1)),
+ INT2FIX(2));
+
r = f_sub(m_real_jd(x), half_days_in_day);
+ df = m_df(x);
+ if (df)
+ r = f_add(r, isec_to_day(df));
+ sf = m_sf(x);
+ if (f_nonzero_p(sf))
+ r = f_add(r, ns_to_day(sf));
+
+ return r;
+}
+
+static VALUE
+m_amjd(union DateData *x)
+{
+ VALUE r, sf;
+ int df;
+
+ r = rb_rational_new1(f_sub(m_real_jd(x), INT2FIX(2400001)));
+
if (simple_dat_p(x))
return r;
df = m_df(x);
if (df)
r = f_add(r, isec_to_day(df));
-
sf = m_sf(x);
if (f_nonzero_p(sf))
r = f_add(r, ns_to_day(sf));
@@ -1250,7 +1497,7 @@ m_ajd(union DateData *x)
return r;
}
-static int
+inline static int
m_of(union DateData *x)
{
if (simple_dat_p(x))
@@ -1267,7 +1514,7 @@ m_of_in_day(union DateData *x)
return isec_to_day(m_of(x));
}
-static double
+inline static double
m_sg(union DateData *x)
{
if (simple_dat_p(x))
@@ -1285,10 +1532,12 @@ m_julian_p(union DateData *x)
double sg;
if (simple_dat_p(x)) {
+ get_s_jd(x);
jd = x->s.jd;
sg = s_sg(x);
}
else {
+ get_c_jd(x);
jd = x->c.jd;
sg = c_sg(x);
}
@@ -1297,13 +1546,35 @@ m_julian_p(union DateData *x)
return jd < sg;
}
-static int
+inline static int
m_gregorian_p(union DateData *x)
{
return !m_julian_p(x);
}
-static int
+inline static int
+m_proleptic_julian_p(union DateData *x)
+{
+ double sg;
+
+ sg = m_sg(x);
+ if (isinf(sg) && sg > 0)
+ return 1;
+ return 0;
+}
+
+inline static int
+m_proleptic_gregorian_p(union DateData *x)
+{
+ double sg;
+
+ sg = m_sg(x);
+ if (isinf(sg) && sg < 0)
+ return 1;
+ return 0;
+}
+
+inline static int
m_year(union DateData *x)
{
if (simple_dat_p(x)) {
@@ -1325,6 +1596,9 @@ m_real_year(union DateData *x)
nth = m_nth(x);
year = m_year(x);
+ if (f_zero_p(nth))
+ return INT2FIX(year);
+
encode_year(nth, year,
m_gregorian_p(x) ? -1 : +1,
&ry);
@@ -1333,21 +1607,22 @@ m_real_year(union DateData *x)
#ifdef USE_PACK
-static int
-m_pd(union DateData *x)
+inline static int
+m_pc(union DateData *x)
{
if (simple_dat_p(x)) {
get_s_civil(x);
- return x->s.pd;
+ return x->s.pc;
}
else {
get_c_civil(x);
- return x->c.pd;
+ get_c_time(x);
+ return x->c.pc;
}
}
#endif
-static int
+inline static int
m_mon(union DateData *x)
{
if (simple_dat_p(x)) {
@@ -1355,7 +1630,7 @@ m_mon(union DateData *x)
#ifndef USE_PACK
return x->s.mon;
#else
- return EX_MON(x->s.pd);
+ return EX_MON(x->s.pc);
#endif
}
else {
@@ -1363,12 +1638,12 @@ m_mon(union DateData *x)
#ifndef USE_PACK
return x->c.mon;
#else
- return EX_MON(x->c.pd);
+ return EX_MON(x->c.pc);
#endif
}
}
-static int
+inline static int
m_mday(union DateData *x)
{
if (simple_dat_p(x)) {
@@ -1376,7 +1651,7 @@ m_mday(union DateData *x)
#ifndef USE_PACK
return x->s.mday;
#else
- return EX_MDAY(x->s.pd);
+ return EX_MDAY(x->s.pc);
#endif
}
else {
@@ -1384,22 +1659,7 @@ m_mday(union DateData *x)
#ifndef USE_PACK
return x->c.mday;
#else
- return EX_MDAY(x->c.pd);
-#endif
- }
-}
-
-static int
-m_hour(union DateData *x)
-{
- if (simple_dat_p(x))
- return 0;
- else {
- get_c_time(x);
-#ifndef USE_PACK
- return x->c.hour;
-#else
- return EX_HOUR(x->c.pd);
+ return EX_MDAY(x->c.pc);
#endif
}
}
@@ -1410,29 +1670,53 @@ static const int yeartab[2][13] = {
};
static int
-c_gregorian_to_yday(int y, int m, int d)
+c_julian_to_yday(int y, int m, int d)
{
- return yeartab[c_leap_p(y) ? 1 : 0][m] + d;
+ assert(m >= 1 && m <= 12);
+ return yeartab[c_julian_leap_p(y) ? 1 : 0][m] + d;
}
-static void c_jd_to_ordinal(int, double, int *, int *);
+static int
+c_gregorian_to_yday(int y, int m, int d)
+{
+ assert(m >= 1 && m <= 12);
+ return yeartab[c_gregorian_leap_p(y) ? 1 : 0][m] + d;
+}
static int
m_yday(union DateData *x)
{
- double sg;
int jd, ry, rd;
+ double sg;
- sg = m_sg(x);
jd = m_local_jd(x);
- if ((isinf(sg) && sg < 0) ||
+ sg = x_sg(x); /* !=m_sg() */
+
+ if (m_proleptic_gregorian_p(x) ||
(jd - sg) > 366)
return c_gregorian_to_yday(m_year(x), m_mon(x), m_mday(x));
+ if (m_proleptic_julian_p(x))
+ return c_julian_to_yday(m_year(x), m_mon(x), m_mday(x));
c_jd_to_ordinal(jd, sg, &ry, &rd);
return rd;
}
-static int
+inline static int
+m_hour(union DateData *x)
+{
+ if (simple_dat_p(x))
+ return 0;
+ else {
+ get_c_time(x);
+#ifndef USE_PACK
+ return x->c.hour;
+#else
+ return EX_HOUR(x->c.pc);
+#endif
+ }
+}
+
+inline static int
m_min(union DateData *x)
{
if (simple_dat_p(x))
@@ -1442,12 +1726,12 @@ m_min(union DateData *x)
#ifndef USE_PACK
return x->c.min;
#else
- return EX_MIN(x->c.pd);
+ return EX_MIN(x->c.pc);
#endif
}
}
-static int
+inline static int
m_sec(union DateData *x)
{
if (simple_dat_p(x))
@@ -1457,7 +1741,7 @@ m_sec(union DateData *x)
#ifndef USE_PACK
return x->c.sec;
#else
- return EX_SEC(x->c.pd);
+ return EX_SEC(x->c.pc);
#endif
}
}
@@ -1708,6 +1992,8 @@ valid_ordinal_p(VALUE y, int d, double sg,
int jd;
r = c_valid_ordinal_p(FIX2INT(y), d, sg, rd, &jd, ns);
+ if (!r)
+ return 0;
decode_jd(INT2FIX(jd), nth, rjd);
if (f_zero_p(*nth))
*ry = FIX2INT(y);
@@ -1745,6 +2031,8 @@ valid_civil_p(VALUE y, int m, int d, double sg,
int jd;
r = c_valid_civil_p(FIX2INT(y), m, d, sg, rm, rd, &jd, ns);
+ if (!r)
+ return 0;
decode_jd(INT2FIX(jd), nth, rjd);
if (f_zero_p(*nth))
*ry = FIX2INT(y);
@@ -1753,6 +2041,13 @@ valid_civil_p(VALUE y, int m, int d, double sg,
decode_year(y, ns ? -1 : +1, &nth2, ry);
}
}
+ else if (style > 1) {
+ decode_year(y, style, nth, ry);
+ r = c_valid_julian_p(*ry, m, d, rm, rd);
+ if (!r)
+ return 0;
+ c_civil_to_jd(*ry, *rm, *rd, style, rjd, ns);
+ }
else {
decode_year(y, style, nth, ry);
r = c_valid_civil_p(*ry, m, d, style, rm, rd, rjd, ns);
@@ -1773,6 +2068,8 @@ valid_commercial_p(VALUE y, int w, int d, double sg,
int jd;
r = c_valid_commercial_p(FIX2INT(y), w, d, sg, rw, rd, &jd, ns);
+ if (!r)
+ return 0;
decode_jd(INT2FIX(jd), nth, rjd);
if (f_zero_p(*nth))
*ry = FIX2INT(y);
@@ -1801,6 +2098,8 @@ valid_weeknum_p(VALUE y, int w, int d, int f, double sg,
int jd;
r = c_valid_weeknum_p(FIX2INT(y), w, d, f, sg, rw, rd, &jd, ns);
+ if (!r)
+ return 0;
decode_jd(INT2FIX(jd), nth, rjd);
if (f_zero_p(*nth))
*ry = FIX2INT(y);
@@ -1830,6 +2129,8 @@ valid_nth_kday_p(VALUE y, int m, int n, int k, double sg,
int jd;
r = c_valid_nth_kday_p(FIX2INT(y), m, n, k, sg, rm, rn, rk, &jd, ns);
+ if (!r)
+ return 0;
decode_jd(INT2FIX(jd), nth, rjd);
if (f_zero_p(*nth))
*ry = FIX2INT(y);
@@ -1846,8 +2147,6 @@ valid_nth_kday_p(VALUE y, int m, int n, int k, double sg,
}
#endif
-/* date light */
-
VALUE date_zone_to_diff(VALUE);
static int
@@ -1876,6 +2175,11 @@ offset_to_sec(VALUE vof, int *rof)
rb_warning("fraction of offset is ignored");
return 1;
}
+ default:
+ if (!k_numeric_p(vof))
+ rb_raise(rb_eTypeError, "expected numeric");
+ vof = f_to_r(vof);
+ /* fall through */
case T_RATIONAL:
{
VALUE vs = day_to_sec(vof);
@@ -1915,9 +2219,20 @@ offset_to_sec(VALUE vof, int *rof)
return 0;
}
+/* date */
+
+#define valid_sg(sg) \
+{\
+ if (!c_valid_start_p(sg)) {\
+ sg = 0;\
+ rb_warning("invalid start is ignored");\
+ }\
+}
+
static VALUE
valid_jd_sub(int argc, VALUE *argv, VALUE klass, int need_jd)
{
+ valid_sg(argv[1]);
return argv[0];
}
@@ -1932,9 +2247,9 @@ date_s__valid_jd_p(int argc, VALUE *argv, VALUE klass)
argv2[0] = vjd;
if (argc < 2)
- argv[1] = DBL2NUM(GREGORIAN);
+ argv2[1] = DBL2NUM(GREGORIAN);
else
- argv[1] = vsg;
+ argv2[1] = vsg;
return valid_jd_sub(2, argv2, klass, 1);
}
@@ -1957,23 +2272,15 @@ date_s_valid_jd_p(int argc, VALUE *argv, VALUE klass)
argv2[0] = vjd;
if (argc < 2)
- argv[1] = INT2FIX(DEFAULT_SG);
+ argv2[1] = INT2FIX(DEFAULT_SG);
else
- argv[1] = vsg;
+ argv2[1] = vsg;
if (NIL_P(valid_jd_sub(2, argv2, klass, 0)))
return Qfalse;
return Qtrue;
}
-#define valid_sg(sg) \
-{\
- if (!c_valid_start_p(sg)) {\
- sg = 0;\
- rb_warning("invalid start is ignored");\
- }\
-}
-
static VALUE
valid_civil_sub(int argc, VALUE *argv, VALUE klass, int need_jd)
{
@@ -1988,7 +2295,7 @@ valid_civil_sub(int argc, VALUE *argv, VALUE klass, int need_jd)
valid_sg(sg);
- if (!need_jd && isinf(sg) && sg < 0) {
+ if (!need_jd && (style_p(y, sg) < 0)) {
if (!valid_gregorian_p(y, m, d,
&nth, &ry,
&rm, &rd))
@@ -2407,9 +2714,11 @@ date_s_zone_to_diff(VALUE klass, VALUE str)
static VALUE
date_s_julian_leap_p(VALUE klass, VALUE y)
{
- if (f_zero_p(f_mod(y, INT2FIX(4))))
- return Qtrue;
- return Qfalse;
+ VALUE nth;
+ int ry;
+
+ decode_year(y, +1, &nth, &ry);
+ return f_boolcast(c_julian_leap_p(ry));
}
/*
@@ -2422,17 +2731,23 @@ date_s_julian_leap_p(VALUE klass, VALUE y)
static VALUE
date_s_gregorian_leap_p(VALUE klass, VALUE y)
{
- if (f_zero_p(f_mod(y, INT2FIX(4))) &&
- f_nonzero_p(f_mod(y, INT2FIX(100))) ||
- f_zero_p(f_mod(y, INT2FIX(400))))
- return Qtrue;
- return Qfalse;
+ VALUE nth;
+ int ry;
+
+ decode_year(y, -1, &nth, &ry);
+ return f_boolcast(c_gregorian_leap_p(ry));
}
static void
-d_simple_gc_mark(struct SimpleDateData *dat)
+d_lite_gc_mark(union DateData *dat)
{
- rb_gc_mark(dat->nth);
+ if (simple_dat_p(dat))
+ rb_gc_mark(dat->s.nth);
+ else {
+ rb_gc_mark(dat->c.nth);
+ rb_gc_mark(dat->c.sf);
+
+ }
}
inline static VALUE
@@ -2446,32 +2761,14 @@ d_simple_new_internal(VALUE klass,
VALUE obj;
obj = Data_Make_Struct(klass, struct SimpleDateData,
- d_simple_gc_mark, -1, dat);
-
- dat->nth = nth;
- dat->jd = jd;
- dat->sg = sg;
- dat->year = y;
-#ifndef USE_PACK
- dat->mon = m;
- dat->mday = d;
-#else
- dat->pd = PACK2(m, d);
-#endif
- dat->flags = flags;
+ d_lite_gc_mark, -1, dat);
+ set_to_simple(dat, nth, jd, sg, y, m, d, flags & ~COMPLEX_DAT);
assert(have_jd_p(dat) || have_civil_p(dat));
return obj;
}
-static void
-d_complex_gc_mark(struct ComplexDateData *dat)
-{
- rb_gc_mark(dat->nth);
- rb_gc_mark(dat->sf);
-}
-
inline static VALUE
d_complex_new_internal(VALUE klass,
VALUE nth, int jd,
@@ -2485,25 +2782,9 @@ d_complex_new_internal(VALUE klass,
VALUE obj;
obj = Data_Make_Struct(klass, struct ComplexDateData,
- d_complex_gc_mark, -1, dat);
-
- dat->nth = nth;
- dat->jd = jd;
- dat->df = df;
- dat->sf = sf;
- dat->of = of;
- dat->sg = sg;
- dat->year = y;
-#ifndef USE_PACK
- dat->mon = m;
- dat->mday = d;
- dat->hour = h;
- dat->min = min;
- dat->sec = s;
-#else
- dat->pd = PACK5(m, d, h, min, s);
-#endif
- dat->flags = flags | COMPLEX_DAT;
+ d_lite_gc_mark, -1, dat);
+ set_to_complex(dat, nth, jd, df, sf, of, sg,
+ y, m, d, h, min, s, flags | COMPLEX_DAT);
assert(have_jd_p(dat) || have_civil_p(dat));
assert(have_df_p(dat) || have_time_p(dat));
@@ -2511,62 +2792,38 @@ d_complex_new_internal(VALUE klass,
return obj;
}
-static void
-d_date_gc_mark(union DateData *dat)
+static VALUE
+d_lite_s_alloc_simple(VALUE klass)
{
- if (simple_dat_p(dat))
- rb_gc_mark(dat->s.nth);
- else {
- rb_gc_mark(dat->c.nth);
- rb_gc_mark(dat->c.sf);
- }
+ return d_simple_new_internal(klass,
+ INT2FIX(0), 0,
+ DEFAULT_SG,
+ 0, 0, 0,
+ HAVE_JD);
}
-inline static VALUE
-d_date_new_internal(VALUE klass,
- VALUE nth, int jd,
- double sg,
- int y, int m, int d,
- unsigned flags)
+static VALUE
+d_lite_s_alloc_complex(VALUE klass)
{
- union DateData *dat;
- VALUE obj;
-
- obj = Data_Make_Struct(klass, union DateData,
- d_date_gc_mark, -1, dat);
-
- dat->s.nth = nth;
- dat->s.jd = jd;
- dat->s.sg = sg;
- dat->s.year = y;
-#ifndef USE_PACK
- dat->s.mon = m;
- dat->s.mday = d;
-#else
- dat->s.pd = PACK2(m, d);
-#endif
- dat->s.flags = flags;
-
- assert(have_jd_p(dat) || have_civil_p(dat));
-
- return obj;
+ return d_complex_new_internal(klass,
+ INT2FIX(0), 0,
+ 0, INT2FIX(0),
+ 0, DEFAULT_SG,
+ 0, 0, 0,
+ 0, 0, 0,
+ HAVE_JD | HAVE_DF);
}
static VALUE
d_lite_s_alloc(VALUE klass)
{
- return d_date_new_internal(klass,
- INT2FIX(0), 0,
- DEFAULT_SG,
- 0, 0, 0,
- HAVE_JD);
+ return d_lite_s_alloc_complex(klass);
}
static void
old_to_new(VALUE ajd, VALUE of, VALUE sg,
VALUE *rnth, int *rjd, int *rdf, VALUE *rsf,
- int *rof, double *rsg,
- unsigned *flags)
+ int *rof, double *rsg)
{
VALUE jd, df, sf, of2, t;
@@ -2585,7 +2842,13 @@ old_to_new(VALUE ajd, VALUE of, VALUE sg,
*rof = NUM2INT(of2);
*rsg = NUM2DBL(sg);
- if (*rof < -1 || *rof > 1) {
+ if (*rdf < 0 || *rdf >= DAY_IN_SECONDS)
+ rb_raise(rb_eArgError, "invalid day fraction");
+
+ if (f_lt_p(*rsf, INT2FIX(0)) ||
+ f_ge_p(*rsf, INT2FIX(SECOND_IN_NANOSECONDS)))
+
+ if (*rof < -DAY_IN_SECONDS || *rof > DAY_IN_SECONDS) {
*rof = 0;
rb_warning("invalid offset is ignored");
}
@@ -2594,8 +2857,6 @@ old_to_new(VALUE ajd, VALUE of, VALUE sg,
*rsg = DEFAULT_SG;
rb_warning("invalid start is ignored");
}
-
- *flags = HAVE_JD | HAVE_DF | COMPLEX_DAT;
}
#ifndef NDEBUG
@@ -2605,7 +2866,6 @@ date_s_new_bang(int argc, VALUE *argv, VALUE klass)
VALUE ajd, of, sg, nth, sf;
int jd, df, rof;
double rsg;
- unsigned flags;
rb_scan_args(argc, argv, "03", &ajd, &of, &sg);
@@ -2619,15 +2879,22 @@ date_s_new_bang(int argc, VALUE *argv, VALUE klass)
}
old_to_new(ajd, of, sg,
- &nth, &jd, &df, &sf, &rof, &rsg, &flags);
+ &nth, &jd, &df, &sf, &rof, &rsg);
- return d_complex_new_internal(klass,
- nth, jd,
- df, sf,
- rof, rsg,
- 0, 0, 0,
- 0, 0, 0,
- flags);
+ if (!df && f_zero_p(sf) && !rof)
+ return d_simple_new_internal(klass,
+ nth, jd,
+ rsg,
+ 0, 0, 0,
+ HAVE_JD);
+ else
+ return d_complex_new_internal(klass,
+ nth, jd,
+ df, sf,
+ rof, rsg,
+ 0, 0, 0,
+ 0, 0, 0,
+ HAVE_JD | HAVE_DF);
}
#endif
@@ -2642,14 +2909,15 @@ integer_p(VALUE x)
case T_FLOAT:
{
double d = NUM2DBL(x);
- if (round(d) == d)
- return 1;
+ return round(d) == d;
}
+ break;
case T_RATIONAL:
{
- if (RRATIONAL(x)->den == 1)
- return 1;
+ VALUE den = RRATIONAL(x)->den;
+ return FIXNUM_P(den) && FIX2LONG(den) == 1;
}
+ break;
}
return 0;
}
@@ -2790,7 +3058,6 @@ date_s_jd(int argc, VALUE *argv, VALUE klass)
int rjd;
decode_jd(jd, &nth, &rjd);
-
ret = d_simple_new_internal(klass,
nth, rjd,
sg,
@@ -2904,7 +3171,7 @@ date_s_civil(int argc, VALUE *argv, VALUE klass)
y = vy;
}
- if (isinf(sg) && sg < 0) {
+ if (style_p(y, sg) < 0) {
VALUE nth;
int ry, rm, rd;
@@ -3213,7 +3480,7 @@ static VALUE
fv_values_at(VALUE h, VALUE a)
{
return rb_funcall2(h, rb_intern("values_at"),
- RARRAY_LENINT(a), RARRAY_PTR(a));
+ RARRAY_LENINT(a), RARRAY_PTR(a));
}
static VALUE d_lite_wday(VALUE);
@@ -3638,7 +3905,6 @@ d_new_by_frags(VALUE klass, VALUE hash, VALUE sg)
int rjd;
decode_jd(jd, &nth, &rjd);
-
return d_simple_new_internal(klass,
nth, rjd,
NUM2DBL(sg),
@@ -3647,9 +3913,8 @@ d_new_by_frags(VALUE klass, VALUE hash, VALUE sg)
}
}
-VALUE
-date__strptime(const char *str, size_t slen,
- const char *fmt, size_t flen, VALUE hash);
+VALUE date__strptime(const char *str, size_t slen,
+ const char *fmt, size_t flen, VALUE hash);
static VALUE
date_s__strptime_internal(int argc, VALUE *argv, VALUE klass,
@@ -3759,8 +4024,7 @@ date_s_strptime(int argc, VALUE *argv, VALUE klass)
}
}
-VALUE
-date__parse(VALUE str, VALUE comp);
+VALUE date__parse(VALUE str, VALUE comp);
static VALUE
date_s__parse_internal(int argc, VALUE *argv, VALUE klass)
@@ -4090,119 +4354,117 @@ date_s_jisx0301(int argc, VALUE *argv, VALUE klass)
}
}
-#ifndef NDEBUG
static VALUE
-d_lite_fill(VALUE self)
+dup_obj(VALUE self)
{
- get_d1(self);
+ get_d1a(self);
- if (simple_dat_p(dat)) {
- get_s_jd(dat);
- get_s_civil(dat);
+ if (simple_dat_p(adat)) {
+ VALUE new = d_lite_s_alloc_simple(CLASS_OF(self));
+ {
+ get_d1b(new);
+ bdat->s = adat->s;
+ return new;
+ }
}
else {
- get_c_jd(dat);
- get_c_civil(dat);
- get_c_df(dat);
- get_c_time(dat);
+ VALUE new = d_lite_s_alloc_complex(CLASS_OF(self));
+ {
+ get_d1b(new);
+ bdat->c = adat->c;
+ return new;
+ }
}
- return self;
}
-#endif
static VALUE
-copy_obj(VALUE self)
+dup_obj_as_complex(VALUE self)
{
- get_d1(self);
+ get_d1a(self);
- if (simple_dat_p(dat))
- return d_simple_new_internal(CLASS_OF(self),
- dat->s.nth,
- dat->s.jd,
- dat->s.sg,
- dat->s.year,
-#ifndef USE_PACK
- dat->s.mon,
- dat->s.mday,
-#else
- EX_MON(dat->s.pd),
- EX_MDAY(dat->s.pd),
-#endif
- dat->s.flags);
- else
- return d_complex_new_internal(CLASS_OF(self),
- dat->c.nth,
- dat->c.jd,
- dat->c.df,
- dat->c.sf,
- dat->c.of,
- dat->c.sg,
- dat->c.year,
-#ifndef USE_PACK
- dat->c.mon,
- dat->c.mday,
- dat->c.hour,
- dat->c.min,
- dat->c.sec,
-#else
- EX_MON(dat->c.pd),
- EX_MDAY(dat->c.pd),
- EX_HOUR(dat->c.pd),
- EX_MIN(dat->c.pd),
- EX_SEC(dat->c.pd),
-#endif
- dat->c.flags);
+ if (simple_dat_p(adat)) {
+ VALUE new = d_lite_s_alloc_complex(CLASS_OF(self));
+ {
+ get_d1b(new);
+ copy_simple_to_complex(&bdat->c, &adat->s);
+ bdat->c.flags |= HAVE_DF | COMPLEX_DAT;
+ return new;
+ }
+ }
+ else {
+ VALUE new = d_lite_s_alloc_complex(CLASS_OF(self));
+ {
+ get_d1b(new);
+ bdat->c = adat->c;
+ return new;
+ }
+ }
}
+#define val2off(vof,iof) \
+{\
+ if (!offset_to_sec(vof, &iof)) {\
+ iof = 0;\
+ rb_warning("invalid offset is ignored");\
+ }\
+}
+
+#ifndef NDEBUG
static VALUE
-copy_obj_as_complex(VALUE self)
+d_lite_initialize(int argc, VALUE *argv, VALUE self)
{
- get_d1(self);
+ VALUE jd, vjd, vdf, sf, vsf, vof, vsg;
+ int df, of;
+ double sg;
- if (simple_dat_p(dat))
- return d_complex_new_internal(CLASS_OF(self),
- dat->s.nth,
- dat->s.jd,
- 0,
- INT2FIX(0),
- 0,
- dat->s.sg,
- dat->s.year,
-#ifndef USE_PACK
- dat->s.mon,
- dat->s.mday,
-#else
- EX_MON(dat->s.pd),
- EX_MDAY(dat->s.pd),
-#endif
- 0,
- 0,
- 0,
- dat->s.flags | HAVE_DF);
- else
- return d_complex_new_internal(CLASS_OF(self),
- dat->c.nth,
- dat->c.jd,
- dat->c.df,
- dat->c.sf,
- dat->c.of,
- dat->c.sg,
- dat->c.year,
-#ifndef USE_PACK
- dat->c.mon,
- dat->c.mday,
- dat->c.hour,
- dat->c.min,
- dat->c.sec,
-#else
- EX_MON(dat->c.pd),
- EX_MDAY(dat->c.pd),
- EX_HOUR(dat->c.pd),
- EX_MIN(dat->c.pd),
- EX_SEC(dat->c.pd),
-#endif
- dat->c.flags);
+ rb_scan_args(argc, argv, "05", &vjd, &vdf, &vsf, &vof, &vsg);
+
+ jd = INT2FIX(0);
+ df = 0;
+ sf = INT2FIX(0);
+ of = 0;
+ sg = DEFAULT_SG;
+
+ switch (argc) {
+ case 5:
+ val2sg(vsg, sg);
+ case 4:
+ val2off(vof, of);
+ case 3:
+ sf = vsf;
+ if (f_lt_p(sf, INT2FIX(0)) ||
+ f_ge_p(sf, INT2FIX(SECOND_IN_NANOSECONDS)))
+ rb_raise(rb_eArgError, "invalid second fraction");
+ case 2:
+ df = NUM2INT(vdf);
+ if (df < 0 || df >= DAY_IN_SECONDS)
+ rb_raise(rb_eArgError, "invalid day fraction");
+ case 1:
+ jd = vjd;
+ }
+
+ {
+ VALUE nth;
+ int rjd;
+
+ get_d1(self);
+
+ decode_jd(jd, &nth, &rjd);
+ if (!df && f_zero_p(sf) && !of) {
+ set_to_simple(&dat->s, nth, rjd, sg, 0, 0, 0, HAVE_JD);
+ }
+ else {
+ if (!complex_dat_p(dat))
+ rb_raise(rb_eArgError,
+ "cannot load complex into simple");
+
+ set_to_complex(&dat->c, nth, rjd, df, sf, of, sg,
+ 0, 0, 0, 0, 0, 0, HAVE_JD | HAVE_DF | COMPLEX_DAT);
+ }
+ }
+ return self;
}
+#endif
/* :nodoc: */
static VALUE
@@ -4213,41 +4475,41 @@ d_lite_initialize_copy(VALUE copy, VALUE date)
{
get_d2(copy, date);
if (simple_dat_p(bdat)) {
- adat->s.nth = bdat->s.nth;
- adat->s.jd = bdat->s.jd;
- adat->s.sg = bdat->s.sg;
- adat->s.year = bdat->s.year;
-#ifndef USE_PACK
- adat->s.mon = bdat->s.mon;
- adat->s.mday = bdat->s.mday;
-#else
- adat->s.pd = bdat->s.pd;
-#endif
- adat->s.flags = bdat->s.flags;
+ adat->s = bdat->s;
+ adat->s.flags &= ~COMPLEX_DAT;
}
else {
- adat->c.nth = bdat->c.nth;
- adat->c.jd = bdat->c.jd;
- adat->c.df = bdat->c.df;
- adat->c.sf = bdat->c.sf;
- adat->c.of = bdat->c.of;
- adat->c.sg = bdat->c.sg;
- adat->c.year = bdat->c.year;
-#ifndef USE_PACK
- adat->c.mon = bdat->c.mon;
- adat->c.mday = bdat->c.mday;
- adat->c.hour = bdat->c.hour;
- adat->c.min = bdat->c.min;
- adat->c.sec = bdat->c.sec;
-#else
- adat->c.pd = bdat->c.pd;
-#endif
- adat->c.flags = bdat->c.flags | COMPLEX_DAT;
+ if (!complex_dat_p(adat))
+ rb_raise(rb_eArgError,
+ "cannot load complex into simple");
+
+ adat->c = bdat->c;
+ adat->c.flags |= COMPLEX_DAT;
}
}
return copy;
}
+#ifndef NDEBUG
+static VALUE
+d_lite_fill(VALUE self)
+{
+ get_d1(self);
+
+ if (simple_dat_p(dat)) {
+ get_s_jd(dat);
+ get_s_civil(dat);
+ }
+ else {
+ get_c_jd(dat);
+ get_c_civil(dat);
+ get_c_df(dat);
+ get_c_time(dat);
+ }
+ return self;
+}
+#endif
+
/*
* call-seq:
* d.ajd
@@ -4270,37 +4532,8 @@ d_lite_ajd(VALUE self)
static VALUE
d_lite_amjd(VALUE self)
{
- VALUE r, sf;
- int df;
-
get_d1(self);
-
- r = rb_rational_new1(f_sub(m_real_jd(dat), INT2FIX(2400001)));
-
- if (simple_dat_p(dat))
- return r;
-
- df = m_df(dat);
- if (df)
- r = f_add(r, isec_to_day(df));
-
- sf = m_sf(dat);
- if (f_nonzero_p(sf))
- r = f_add(r, ns_to_day(sf));
- return r;
-}
-
-#define return_once(k, expr)\
-{\
- VALUE id, val;\
- get_d1(self);\
- id = ID2SYM(rb_intern(#k));\
- val = rb_hash_aref(dat->r.cache, id);\
- if (!NIL_P(val))\
- return val;\
- val = expr;\
- rb_hash_aset(dat->r.cache, id, val);\
- return val;\
+ return m_amjd(dat);
}
/*
@@ -4421,7 +4654,7 @@ d_lite_wnum0(VALUE self)
int ry, rw, rd;
get_d1(self);
- c_jd_to_weeknum(m_local_jd(dat), 0, m_sg(dat),
+ c_jd_to_weeknum(m_local_jd(dat), 0, x_sg(dat), /* !=m_sg() */
&ry, &rw, &rd);
return INT2FIX(rw);
}
@@ -4432,7 +4665,7 @@ d_lite_wnum1(VALUE self)
int ry, rw, rd;
get_d1(self);
- c_jd_to_weeknum(m_local_jd(dat), 1, m_sg(dat),
+ c_jd_to_weeknum(m_local_jd(dat), 1, x_sg(dat), /* !=m_sg() */
&ry, &rw, &rd);
return INT2FIX(rw);
}
@@ -4528,13 +4761,15 @@ d_lite_zone(VALUE self)
static VALUE
d_lite_cwyear(VALUE self)
{
+ double sg;
int ry, rw, rd;
VALUE ry2;
get_d1(self);
- c_jd_to_commercial(m_local_jd(dat), m_sg(dat),
+ sg = x_sg(dat); /* !=m_sg() */
+ c_jd_to_commercial(m_local_jd(dat), sg,
&ry, &rw, &rd);
- encode_year(m_nth(dat), ry, +1, &ry2);
+ encode_year(m_nth(dat), ry, sg, &ry2);
return ry2;
}
@@ -4550,7 +4785,7 @@ d_lite_cweek(VALUE self)
int ry, rw, rd;
get_d1(self);
- c_jd_to_commercial(m_local_jd(dat), m_sg(dat),
+ c_jd_to_commercial(m_local_jd(dat), x_sg(dat), /* !=m_sg() */
&ry, &rw, &rd);
return INT2FIX(rw);
}
@@ -4681,7 +4916,7 @@ d_lite_saturday_p(VALUE self)
#ifndef NDEBUG
static VALUE
-generic_nth_kday_p(VALUE self, VALUE n, VALUE k)
+d_lite_nth_kday_p(VALUE self, VALUE n, VALUE k)
{
int rjd, ns;
@@ -4691,7 +4926,7 @@ generic_nth_kday_p(VALUE self, VALUE n, VALUE k)
return Qfalse;
c_nth_kday_to_jd(m_year(dat), m_mon(dat),
- NUM2INT(n), NUM2INT(k), m_sg(dat),
+ NUM2INT(n), NUM2INT(k), x_sg(dat), /* !=m_sg() */
&rjd, &ns);
if (m_local_jd(dat) != rjd)
return Qfalse;
@@ -4736,13 +4971,11 @@ d_lite_gregorian_p(VALUE self)
static VALUE
d_lite_leap_p(VALUE self)
{
- double sg;
int rjd, ns, ry, rm, rd;
get_d1(self);
- sg = m_sg(dat);
- if (isinf(sg) && sg < 0)
- return f_boolcast(c_leap_p(m_year(dat)));
+ if (m_gregorian_p(dat))
+ return f_boolcast(c_gregorian_leap_p(m_year(dat)));
c_civil_to_jd(m_year(dat), 3, 1, fix_style(dat),
&rjd, &ns);
@@ -4772,7 +5005,7 @@ clear_civil(union DateData *x)
x->s.mon = 0;
x->s.mday = 0;
#else
- x->s.pd = 0;
+ x->s.pc = 0;
#endif
x->s.flags &= ~HAVE_CIVIL;
}
@@ -4785,7 +5018,7 @@ clear_civil(union DateData *x)
x->c.min = 0;
x->c.sec = 0;
#else
- x->c.pd = 0;
+ x->c.pc = 0;
#endif
x->c.flags &= ~(HAVE_CIVIL | HAVE_TIME);
}
@@ -4797,24 +5030,24 @@ set_sg(union DateData *x, double sg)
if (simple_dat_p(x)) {
get_s_jd(x);
clear_civil(x);
- x->s.sg = sg;
+ x->s.sg = (sg_cast)sg;
} else {
get_c_jd(x);
get_c_df(x);
clear_civil(x);
- x->c.sg = sg;
+ x->c.sg = (sg_cast)sg;
}
}
static VALUE
-copy_obj_with_new_start(VALUE obj, double sg)
+dup_obj_with_new_start(VALUE obj, double sg)
{
- VALUE copy = copy_obj(obj);
+ volatile VALUE dup = dup_obj(obj);
{
- get_d1(copy);
+ get_d1(dup);
set_sg(dat, sg);
}
- return copy;
+ return dup;
}
/*
@@ -4835,7 +5068,7 @@ d_lite_new_start(int argc, VALUE *argv, VALUE self)
if (argc >= 1)
val2sg(vsg, sg);
- return copy_obj_with_new_start(self, sg);
+ return dup_obj_with_new_start(self, sg);
}
/*
@@ -4848,7 +5081,7 @@ d_lite_new_start(int argc, VALUE *argv, VALUE self)
static VALUE
d_lite_italy(VALUE self)
{
- return copy_obj_with_new_start(self, ITALY);
+ return dup_obj_with_new_start(self, ITALY);
}
/*
@@ -4861,7 +5094,7 @@ d_lite_italy(VALUE self)
static VALUE
d_lite_england(VALUE self)
{
- return copy_obj_with_new_start(self, ENGLAND);
+ return dup_obj_with_new_start(self, ENGLAND);
}
/*
@@ -4874,7 +5107,7 @@ d_lite_england(VALUE self)
static VALUE
d_lite_julian(VALUE self)
{
- return copy_obj_with_new_start(self, JULIAN);
+ return dup_obj_with_new_start(self, JULIAN);
}
/*
@@ -4887,7 +5120,7 @@ d_lite_julian(VALUE self)
static VALUE
d_lite_gregorian(VALUE self)
{
- return copy_obj_with_new_start(self, GREGORIAN);
+ return dup_obj_with_new_start(self, GREGORIAN);
}
static void
@@ -4901,22 +5134,14 @@ set_of(union DateData *x, int of)
}
static VALUE
-copy_obj_with_new_offset(VALUE obj, int of)
+dup_obj_with_new_offset(VALUE obj, int of)
{
- VALUE copy = copy_obj_as_complex(obj);
+ volatile VALUE dup = dup_obj_as_complex(obj);
{
- get_d1(copy);
+ get_d1(dup);
set_of(dat, of);
}
- return copy;
-}
-
-#define val2off(vof,iof) \
-{\
- if (!offset_to_sec(vof, &iof)) {\
- iof = 0;\
- rb_warning("invalid offset is ignored");\
- }\
+ return dup;
}
/*
@@ -4937,7 +5162,7 @@ d_lite_new_offset(int argc, VALUE *argv, VALUE self)
if (argc >= 1)
val2off(vof, rof);
- return copy_obj_with_new_offset(self, rof);
+ return dup_obj_with_new_offset(self, rof);
}
/*
@@ -4972,15 +5197,20 @@ d_lite_plus(VALUE self, VALUE other)
nth = f_add(nth, INT2FIX(DIV(t, CM_PERIOD)));
t = MOD(t, CM_PERIOD);
}
- jd = m_jd(dat) + (int)t;
- if (jd < 0) {
- nth = f_sub(nth, INT2FIX(1));
- jd += CM_PERIOD;
- }
- else if (jd >= CM_PERIOD) {
- nth = f_add(nth, INT2FIX(1));
- jd -= CM_PERIOD;
+ if (!t)
+ jd = m_jd(dat);
+ else {
+ jd = m_jd(dat) + (int)t;
+
+ if (jd < 0) {
+ nth = f_sub(nth, INT2FIX(1));
+ jd += CM_PERIOD;
+ }
+ else if (jd >= CM_PERIOD) {
+ nth = f_add(nth, INT2FIX(1));
+ jd -= CM_PERIOD;
+ }
}
if (simple_dat_p(dat))
@@ -5023,16 +5253,24 @@ d_lite_plus(VALUE self, VALUE other)
jd = -jd;
}
- jd = m_jd(dat) + jd;
- if (jd < 0) {
- nth = f_sub(nth, INT2FIX(1));
- jd += CM_PERIOD;
- }
- else if (jd >= CM_PERIOD) {
- nth = f_add(nth, INT2FIX(1));
- jd -= CM_PERIOD;
+ if (!jd)
+ jd = m_jd(dat);
+ else {
+ jd = m_jd(dat) + jd;
+ if (jd < 0) {
+ nth = f_sub(nth, INT2FIX(1));
+ jd += CM_PERIOD;
+ }
+ else if (jd >= CM_PERIOD) {
+ nth = f_add(nth, INT2FIX(1));
+ jd -= CM_PERIOD;
+ }
}
- nth = f_add(m_nth(dat), nth);
+
+ if (f_zero_p(nth))
+ nth = m_nth(dat);
+ else
+ nth = f_add(m_nth(dat), nth);
if (simple_dat_p(dat))
return d_simple_new_internal(CLASS_OF(self),
@@ -5095,36 +5333,52 @@ d_lite_plus(VALUE self, VALUE other)
sf = f_negate(sf);
}
- sf = f_add(m_sf(dat), sf);
- if (f_lt_p(sf, INT2FIX(0))) {
- df -= 1;
- sf = f_add(sf, INT2FIX(SECOND_IN_NANOSECONDS));
- }
- else if (f_ge_p(sf, INT2FIX(SECOND_IN_NANOSECONDS))) {
- df += 1;
- sf = f_sub(sf, INT2FIX(SECOND_IN_NANOSECONDS));
+ if (f_zero_p(sf))
+ sf = m_sf(dat);
+ else {
+ sf = f_add(m_sf(dat), sf);
+ if (f_lt_p(sf, INT2FIX(0))) {
+ df -= 1;
+ sf = f_add(sf, INT2FIX(SECOND_IN_NANOSECONDS));
+ }
+ else if (f_ge_p(sf, INT2FIX(SECOND_IN_NANOSECONDS))) {
+ df += 1;
+ sf = f_sub(sf, INT2FIX(SECOND_IN_NANOSECONDS));
+ }
}
- df = m_df(dat) + df;
- if (df < 0) {
- jd -= 1;
- df += DAY_IN_SECONDS;
- }
- else if (df >= DAY_IN_SECONDS) {
- jd += 1;
- df -= DAY_IN_SECONDS;
+ if (!df)
+ df = m_df(dat);
+ else {
+ df = m_df(dat) + df;
+ if (df < 0) {
+ jd -= 1;
+ df += DAY_IN_SECONDS;
+ }
+ else if (df >= DAY_IN_SECONDS) {
+ jd += 1;
+ df -= DAY_IN_SECONDS;
+ }
}
- jd = m_jd(dat) + jd;
- if (jd < 0) {
- nth = f_sub(nth, INT2FIX(1));
- jd += CM_PERIOD;
- }
- else if (jd >= CM_PERIOD) {
- nth = f_add(nth, INT2FIX(1));
- jd -= CM_PERIOD;
+ if (!jd)
+ jd = m_jd(dat);
+ else {
+ jd = m_jd(dat) + jd;
+ if (jd < 0) {
+ nth = f_sub(nth, INT2FIX(1));
+ jd += CM_PERIOD;
+ }
+ else if (jd >= CM_PERIOD) {
+ nth = f_add(nth, INT2FIX(1));
+ jd -= CM_PERIOD;
+ }
}
- nth = f_add(m_nth(dat), nth);
+
+ if (f_zero_p(nth))
+ nth = m_nth(dat);
+ else
+ nth = f_add(m_nth(dat), nth);
if (!df && f_zero_p(sf) && !m_of(dat))
return d_simple_new_internal(CLASS_OF(self),
@@ -5150,11 +5404,15 @@ d_lite_plus(VALUE self, VALUE other)
if (!k_numeric_p(other))
rb_raise(rb_eTypeError, "expected numeric");
other = f_to_r(other);
+ /* fall through */
case T_RATIONAL:
{
VALUE nth, sf, t;
int jd, df, s;
+ if (integer_p(other))
+ return d_lite_plus(self, RRATIONAL(other)->num);
+
if (f_positive_p(other))
s = +1;
else {
@@ -5181,36 +5439,52 @@ d_lite_plus(VALUE self, VALUE other)
sf = f_negate(sf);
}
- sf = f_add(m_sf(dat), sf);
- if (f_lt_p(sf, INT2FIX(0))) {
- df -= 1;
- sf = f_add(sf, INT2FIX(SECOND_IN_NANOSECONDS));
- }
- else if (f_ge_p(sf, INT2FIX(SECOND_IN_NANOSECONDS))) {
- df += 1;
- sf = f_sub(sf, INT2FIX(SECOND_IN_NANOSECONDS));
+ if (f_zero_p(sf))
+ sf = m_sf(dat);
+ else {
+ sf = f_add(m_sf(dat), sf);
+ if (f_lt_p(sf, INT2FIX(0))) {
+ df -= 1;
+ sf = f_add(sf, INT2FIX(SECOND_IN_NANOSECONDS));
+ }
+ else if (f_ge_p(sf, INT2FIX(SECOND_IN_NANOSECONDS))) {
+ df += 1;
+ sf = f_sub(sf, INT2FIX(SECOND_IN_NANOSECONDS));
+ }
}
- df = m_df(dat) + df;
- if (df < 0) {
- jd -= 1;
- df += DAY_IN_SECONDS;
- }
- else if (df >= DAY_IN_SECONDS) {
- jd += 1;
- df -= DAY_IN_SECONDS;
+ if (!df)
+ df = m_df(dat);
+ else {
+ df = m_df(dat) + df;
+ if (df < 0) {
+ jd -= 1;
+ df += DAY_IN_SECONDS;
+ }
+ else if (df >= DAY_IN_SECONDS) {
+ jd += 1;
+ df -= DAY_IN_SECONDS;
+ }
}
- jd = m_jd(dat) + jd;
- if (jd < 0) {
- nth = f_sub(nth, INT2FIX(1));
- jd += CM_PERIOD;
- }
- else if (jd >= CM_PERIOD) {
- nth = f_add(nth, INT2FIX(1));
- jd -= CM_PERIOD;
+ if (!jd)
+ jd = m_jd(dat);
+ else {
+ jd = m_jd(dat) + jd;
+ if (jd < 0) {
+ nth = f_sub(nth, INT2FIX(1));
+ jd += CM_PERIOD;
+ }
+ else if (jd >= CM_PERIOD) {
+ nth = f_add(nth, INT2FIX(1));
+ jd -= CM_PERIOD;
+ }
}
- nth = f_add(m_nth(dat), nth);
+
+ if (f_zero_p(nth))
+ nth = m_nth(dat);
+ else
+ nth = f_add(m_nth(dat), nth);
if (!df && f_zero_p(sf) && !m_of(dat))
return d_simple_new_internal(CLASS_OF(self),
@@ -5498,6 +5772,8 @@ d_lite_prev_year(int argc, VALUE *argv, VALUE self)
return d_lite_lshift(self, f_mul(n, INT2FIX(12)));
}
+static VALUE d_lite_cmp(VALUE, VALUE);
+
/*
* call-seq:
* d.step(limit[, step=1])
@@ -5509,7 +5785,7 @@ d_lite_prev_year(int argc, VALUE *argv, VALUE self)
* date at each step.
*/
static VALUE
-generic_step(int argc, VALUE *argv, VALUE self)
+d_lite_step(int argc, VALUE *argv, VALUE self)
{
VALUE limit, step, date;
@@ -5528,9 +5804,9 @@ generic_step(int argc, VALUE *argv, VALUE self)
date = self;
switch (FIX2INT(f_cmp(step, INT2FIX(0)))) {
case -1:
- while (f_ge_p(date, limit)) {
+ while (FIX2INT(d_lite_cmp(date, limit)) >= 0) {
rb_yield(date);
- date = f_add(date, step);
+ date = d_lite_plus(date, step);
}
break;
case 0:
@@ -5538,9 +5814,9 @@ generic_step(int argc, VALUE *argv, VALUE self)
rb_yield(date);
break;
case 1:
- while (f_le_p(date, limit)) {
+ while (FIX2INT(d_lite_cmp(date, limit)) <= 0) {
rb_yield(date);
- date = f_add(date, step);
+ date = d_lite_plus(date, step);
}
break;
default:
@@ -5558,16 +5834,16 @@ generic_step(int argc, VALUE *argv, VALUE self)
* (inclusive), yielding each date as we go.
*/
static VALUE
-generic_upto(VALUE self, VALUE max)
+d_lite_upto(VALUE self, VALUE max)
{
VALUE date;
RETURN_ENUMERATOR(self, 1, &max);
date = self;
- while (f_le_p(date, max)) {
+ while (FIX2INT(d_lite_cmp(date, max)) <= 0) {
rb_yield(date);
- date = f_add(date, INT2FIX(1));
+ date = d_lite_plus(date, INT2FIX(1));
}
return self;
}
@@ -5581,16 +5857,16 @@ generic_upto(VALUE self, VALUE max)
* (inclusive), yielding each date as we go.
*/
static VALUE
-generic_downto(VALUE self, VALUE min)
+d_lite_downto(VALUE self, VALUE min)
{
VALUE date;
RETURN_ENUMERATOR(self, 1, &min);
date = self;
- while (f_ge_p(date, min)) {
+ while (FIX2INT(d_lite_cmp(date, min)) >= 0) {
rb_yield(date);
- date = f_add(date, INT2FIX(-1));
+ date = d_lite_plus(date, INT2FIX(-1));
}
return self;
}
@@ -5759,8 +6035,8 @@ d_lite_cmp(VALUE self, VALUE other)
return INT2FIX(1);
}
#else
- a_pd = m_pd(adat);
- b_pd = m_pd(bdat);
+ a_pd = m_pc(adat);
+ b_pd = m_pc(bdat);
if (a_pd == b_pd) {
return INT2FIX(0);
}
@@ -5867,8 +6143,8 @@ d_lite_equal(VALUE self, VALUE other)
}
#else
/* mon and mday only */
- a_pd = (m_pd(adat) >> MDAY_SHIFT);
- b_pd = (m_pd(bdat) >> MDAY_SHIFT);
+ a_pd = (m_pc(adat) >> MDAY_SHIFT);
+ b_pd = (m_pc(bdat) >> MDAY_SHIFT);
if (a_pd == b_pd) {
return Qtrue;
}
@@ -5905,10 +6181,20 @@ d_lite_eql_p(VALUE self, VALUE other)
static VALUE
d_lite_hash(VALUE self)
{
+ st_index_t v, h[4];
+
get_d1(self);
- return rb_hash(m_ajd(dat));
+ h[0] = m_nth(dat);
+ h[1] = m_jd(dat);
+ h[2] = m_df(dat);
+ h[3] = m_sf(dat);
+ v = rb_memhash(h, sizeof(h));
+ return LONG2FIX(v);
}
+#define AVOID_SPRINTF_BUG
+#define FMT_TO_S "%.4d-%02d-%02d"
+
/*
* call-seq:
* d.to_s
@@ -5920,14 +6206,17 @@ d_lite_to_s(VALUE self)
{
get_d1(self);
- if (f_zero_p(m_nth(dat)))
- return rb_enc_sprintf(rb_usascii_encoding(),
- "%.4d-%02d-%02d",
+ if (f_zero_p(m_nth(dat))
+#ifdef AVOID_SPRINTF_BUG
+ && m_year(dat) >= 0
+#endif
+ )
+ return rb_enc_sprintf(rb_usascii_encoding(), FMT_TO_S,
m_year(dat), m_mon(dat), m_mday(dat));
else {
VALUE argv[4];
- argv[0] = rb_usascii_str_new2("%.4d-%02d-%02d");
+ argv[0] = rb_usascii_str_new2(FMT_TO_S);
argv[1] = m_real_year(dat);
argv[2] = INT2FIX(m_mon(dat));
argv[3] = INT2FIX(m_mday(dat));
@@ -5935,72 +6224,95 @@ d_lite_to_s(VALUE self)
}
}
+#ifndef NDEBUG
static VALUE
-inspect_flags(VALUE self)
+mk_inspect_flags(union DateData *x)
{
- get_d1(self);
-
return rb_enc_sprintf(rb_usascii_encoding(),
"%c%c%c%c%c",
- (dat->flags & COMPLEX_DAT) ? 'C' : 'S',
- (dat->flags & HAVE_JD) ? 'j' : '-',
- (dat->flags & HAVE_DF) ? 'd' : '-',
- (dat->flags & HAVE_CIVIL) ? 'c' : '-',
- (dat->flags & HAVE_TIME) ? 't' : '-');
+ (x->flags & COMPLEX_DAT) ? 'C' : 'S',
+ (x->flags & HAVE_JD) ? 'j' : '-',
+ (x->flags & HAVE_DF) ? 'd' : '-',
+ (x->flags & HAVE_CIVIL) ? 'c' : '-',
+ (x->flags & HAVE_TIME) ? 't' : '-');
}
-/*
- * call-seq:
- * d.inspect
- *
- * Return internal object state as a programmer-readable string.
- */
static VALUE
-d_lite_inspect(VALUE self)
+mk_inspect_raw(union DateData *x, const char *klass)
{
- get_d1(self);
-
- if (simple_dat_p(dat)) {
+ if (simple_dat_p(x)) {
return rb_enc_sprintf(rb_usascii_encoding(),
- "#<%s: %s "
- "((%sth,%dj),+0s,%.0fj; "
- "%dy%dm%dd; %s)>",
- rb_obj_classname(self),
- RSTRING_PTR(f_to_s(self)),
- RSTRING_PTR(f_inspect(dat->s.nth)),
- dat->s.jd, dat->s.sg,
+ "#<%s: "
+ "(%sth,%dj),+0s,%.0fj; "
+ "%dy%dm%dd; %s>",
+ klass ? klass : "?",
+ RSTRING_PTR(f_inspect(x->s.nth)),
+ x->s.jd, x->s.sg,
#ifndef USE_PACK
- dat->s.year, dat->s.mon, dat->s.mday,
+ x->s.year, x->s.mon, x->s.mday,
#else
- dat->s.year,
- EX_MON(dat->s.pd), EX_MDAY(dat->s.pd),
+ x->s.year,
+ EX_MON(x->s.pc), EX_MDAY(x->s.pc),
#endif
- RSTRING_PTR(inspect_flags(self)));
+ RSTRING_PTR(mk_inspect_flags(x)));
}
else {
return rb_enc_sprintf(rb_usascii_encoding(),
- "#<%s: %s "
- "((%sth,%dj,%ds,%sn),%+ds,%.0fj; "
- "%dy%dm%dd %dh%dm%ds; %s)>",
- rb_obj_classname(self),
- RSTRING_PTR(f_to_s(self)),
- RSTRING_PTR(f_inspect(dat->c.nth)),
- dat->c.jd, dat->c.df,
- RSTRING_PTR(f_inspect(dat->c.sf)),
- dat->c.of, dat->c.sg,
+ "#<%s: "
+ "(%sth,%dj,%ds,%sn),%+ds,%.0fj; "
+ "%dy%dm%dd %dh%dm%ds; %s>",
+ klass ? klass : "?",
+ RSTRING_PTR(f_inspect(x->c.nth)),
+ x->c.jd, x->c.df,
+ RSTRING_PTR(f_inspect(x->c.sf)),
+ x->c.of, x->c.sg,
#ifndef USE_PACK
- dat->c.year, dat->c.mon, dat->c.mday,
- dat->c.hour, dat->c.min, dat->c.sec,
+ x->c.year, x->c.mon, x->c.mday,
+ x->c.hour, x->c.min, x->c.sec,
#else
- dat->c.year,
- EX_MON(dat->c.pd), EX_MDAY(dat->c.pd),
- EX_HOUR(dat->c.pd), EX_MIN(dat->c.pd),
- EX_SEC(dat->c.pd),
+ x->c.year,
+ EX_MON(x->c.pc), EX_MDAY(x->c.pc),
+ EX_HOUR(x->c.pc), EX_MIN(x->c.pc),
+ EX_SEC(x->c.pc),
#endif
- RSTRING_PTR(inspect_flags(self)));
+ RSTRING_PTR(mk_inspect_flags(x)));
}
}
+static VALUE
+d_lite_inspect_raw(VALUE self)
+{
+ get_d1(self);
+ return mk_inspect_raw(dat, rb_obj_classname(self));
+}
+#endif
+
+static VALUE
+mk_inspect(union DateData *x, const char *klass, const char *to_s)
+{
+ return rb_enc_sprintf(rb_usascii_encoding(),
+ "#<%s: %s ((%sj,%ds,%sn),%+ds,%.0fj)>",
+ klass ? klass : "?",
+ to_s ? to_s : "?",
+ RSTRING_PTR(f_inspect(m_real_jd(x))), m_df(x),
+ RSTRING_PTR(f_inspect(m_sf(x))),
+ m_of(x), m_sg(x));
+}
+
+/*
+ * call-seq:
+ * d.inspect
+ *
+ * Return internal object state as a programmer-readable string.
+ */
+static VALUE
+d_lite_inspect(VALUE self)
+{
+ get_d1(self);
+ return mk_inspect(dat, rb_obj_classname(self),
+ RSTRING_PTR(f_to_s(self)));
+}
+
#include <errno.h>
#include "date_tmx.h"
@@ -6218,8 +6530,8 @@ d_lite_rfc2822(VALUE self)
static VALUE
d_lite_httpdate(VALUE self)
{
- VALUE d = copy_obj_with_new_offset(self, 0);
- return strftimev("%a, %d %b %Y %T GMT", d, d_lite_set_tmx);
+ volatile VALUE dup = dup_obj_with_new_offset(self, 0);
+ return strftimev("%a, %d %b %Y %T GMT", dup, d_lite_set_tmx);
}
static VALUE
@@ -6267,6 +6579,28 @@ d_lite_jisx0301(VALUE self)
strftimev(".%m.%d", self, d_lite_set_tmx));
}
+#ifndef NDEBUG
+static VALUE
+d_lite_marshal_dump_old(VALUE self)
+{
+ VALUE a;
+
+ get_d1(self);
+
+ a = rb_ary_new3(3,
+ m_ajd(dat),
+ m_of_in_day(dat),
+ DBL2NUM(m_sg(dat)));
+
+ if (FL_TEST(self, FL_EXIVAR)) {
+ rb_copy_generic_ivar(a, self);
+ FL_SET(a, FL_EXIVAR);
+ }
+
+ return a;
+}
+#endif
+
/*
* call-seq:
* d.marshal_dump
@@ -6316,32 +6650,25 @@ d_lite_marshal_load(VALUE self, VALUE a)
VALUE ajd, of, sg, nth, sf;
int jd, df, rof;
double rsg;
- unsigned flags;
ajd = RARRAY_PTR(a)[0];
of = RARRAY_PTR(a)[1];
sg = RARRAY_PTR(a)[2];
old_to_new(ajd, of, sg,
- &nth, &jd, &df, &sf, &rof, &rsg, &flags);
-
- dat->c.nth = nth;
- dat->c.jd = jd;
- dat->c.df = df;
- dat->c.sf = sf;
- dat->c.of = rof;
- dat->c.sg = rsg;
- dat->c.year = 0;
-#ifndef USE_PACK
- dat->c.mon = 0;
- dat->c.mday = 0;
- dat->c.hour = 0;
- dat->c.min = 0;
- dat->c.sec = 0;
-#else
- dat->c.pd = 0;
-#endif
- dat->c.flags = flags;
+ &nth, &jd, &df, &sf, &rof, &rsg);
+
+ if (!df && f_zero_p(sf) && !rof) {
+ set_to_simple(&dat->s, nth, jd, sg, 0, 0, 0, HAVE_JD);
+ } else {
+ if (!complex_dat_p(dat))
+ rb_raise(rb_eArgError,
+ "cannot load complex into simple");
+
+ set_to_complex(&dat->c, nth, jd, df, sf, rof, rsg,
+ 0, 0, 0, 0, 0, 0,
+ HAVE_JD | HAVE_DF | COMPLEX_DAT);
+ }
}
break;
case 6:
@@ -6356,38 +6683,16 @@ d_lite_marshal_load(VALUE self, VALUE a)
sf = RARRAY_PTR(a)[3];
of = NUM2INT(RARRAY_PTR(a)[4]);
sg = NUM2DBL(RARRAY_PTR(a)[5]);
-
if (!df && f_zero_p(sf) && !of) {
- dat->s.nth = nth;
- dat->s.jd = jd;
- dat->s.sg = sg;
- dat->s.year = 0;
-#ifndef USE_PACK
- dat->s.mon = 0;
- dat->s.mday = 0;
-#else
- dat->s.pd = 0;
-#endif
- dat->s.flags = HAVE_JD;
- }
- else {
- dat->c.nth = nth;
- dat->c.jd = jd;
- dat->c.df = df;
- dat->c.sf = sf;
- dat->c.of = of;
- dat->c.sg = sg;
- dat->c.year = 0;
-#ifndef USE_PACK
- dat->c.mon = 0;
- dat->c.mday = 0;
- dat->c.hour = 0;
- dat->c.min = 0;
- dat->c.sec = 0;
-#else
- dat->c.pd = 0;
-#endif
- dat->c.flags = HAVE_JD | HAVE_DF | COMPLEX_DAT;
+ set_to_simple(&dat->s, nth, jd, sg, 0, 0, 0, HAVE_JD);
+ } else {
+ if (!complex_dat_p(dat))
+ rb_raise(rb_eArgError,
+ "cannot load complex into simple");
+
+ set_to_complex(&dat->c, nth, jd, df, sf, of, sg,
+ 0, 0, 0, 0, 0, 0,
+ HAVE_JD | HAVE_DF | COMPLEX_DAT);
}
}
break;
@@ -6405,7 +6710,7 @@ d_lite_marshal_load(VALUE self, VALUE a)
}
-/* datetime light */
+/* datetime */
/*
* call-seq:
@@ -6618,7 +6923,7 @@ datetime_s_civil(int argc, VALUE *argv, VALUE klass)
y = vy;
}
- if (isinf(sg) && sg < 0) {
+ if (style_p(y, sg) < 0) {
VALUE nth;
int ry, rm, rd, rh, rmin, rs;
@@ -7313,6 +7618,9 @@ datetime_s_jisx0301(int argc, VALUE *argv, VALUE klass)
}
}
+#undef FMT_TO_S
+#define FMT_TO_S "%.4d-%02d-%02d" "T" "%02d:%02d:%02d" "%c%02d:%02d"
+
/*
* call-seq:
* dt.to_s
@@ -7324,14 +7632,15 @@ dt_lite_to_s(VALUE self)
{
get_d1(self);
- if (f_zero_p(m_nth(dat))) {
+ if (f_zero_p(m_nth(dat))
+#ifdef AVOID_SPRINTF_BUG
+ && m_year(dat) >= 0
+#endif
+ ) {
int s, h, m;
decode_offset(m_of(dat), s, h, m);
- return rb_enc_sprintf(rb_usascii_encoding(),
- "%.4d-%02d-%02dT"
- "%02d:%02d:%02d"
- "%c%02d:%02d",
+ return rb_enc_sprintf(rb_usascii_encoding(), FMT_TO_S,
m_year(dat), m_mon(dat), m_mday(dat),
m_hour(dat), m_min(dat), m_sec(dat),
s, h, m);
@@ -7341,9 +7650,7 @@ dt_lite_to_s(VALUE self)
VALUE argv[10];
decode_offset(m_of(dat), s, h, m);
- argv[0] = rb_usascii_str_new2("%.4d-%02d-%02dT"
- "%02d:%02d:%02d"
- "%c%02d:%02d");
+ argv[0] = rb_usascii_str_new2(FMT_TO_S);
argv[1] = m_real_year(dat);
argv[2] = INT2FIX(m_mon(dat));
argv[3] = INT2FIX(m_mday(dat));
@@ -7466,7 +7773,8 @@ dt_lite_jisx0301(int argc, VALUE *argv, VALUE self)
#define f_subsec(x) rb_funcall(x, rb_intern("subsec"), 0)
#define f_utc_offset(x) rb_funcall(x, rb_intern("utc_offset"), 0)
#define f_local3(x,y,m,d) rb_funcall(x, rb_intern("local"), 3, y, m, d)
-#define f_utc6(x,y,m,d,h,min,s) rb_funcall(x, rb_intern("utc"), 6, y, m, d, h, min, s)
+#define f_utc6(x,y,m,d,h,min,s) rb_funcall(x, rb_intern("utc"), 6,\
+ y, m, d, h, min, s)
/*
* call-seq:
@@ -7589,42 +7897,35 @@ date_to_date(VALUE self)
static VALUE
date_to_datetime(VALUE self)
{
- get_d1(self);
+ get_d1a(self);
- if (simple_dat_p(dat))
- return d_simple_new_internal(cDateTime,
- dat->s.nth,
- dat->s.jd,
- dat->s.sg,
- dat->s.year,
-#ifndef USE_PACK
- dat->s.mon,
- dat->s.mday,
-#else
- EX_MON(dat->s.pd),
- EX_MDAY(dat->s.pd),
-#endif
- dat->s.flags);
- else
- return d_complex_new_internal(cDateTime,
- dat->c.nth,
- dat->c.jd,
- 0,
- INT2FIX(0),
- dat->c.of,
- dat->c.sg,
- dat->c.year,
+ if (simple_dat_p(adat)) {
+ VALUE new = d_lite_s_alloc_simple(cDateTime);
+ {
+ get_d1b(new);
+ bdat->s = adat->s;
+ return new;
+ }
+ }
+ else {
+ VALUE new = d_lite_s_alloc_complex(cDateTime);
+ {
+ get_d1b(new);
+ bdat->c = adat->c;
+ bdat->c.df = 0;
+ bdat->c.sf = INT2FIX(0);
#ifndef USE_PACK
- dat->c.mon,
- dat->c.mday,
+ bdat->c.hour = 0;
+ bdat->c.min = 0;
+ bdat->c.sec = 0;
#else
- EX_MON(dat->c.pd),
- EX_MDAY(dat->c.pd),
+ bdat->c.pc = PACK5(EX_MON(adat->c.pc), EX_MDAY(adat->c.pc),
+ 0, 0, 0);
+ bdat->c.flags |= HAVE_DF | HAVE_TIME;
#endif
- 0,
- 0,
- 0,
- dat->c.flags | HAVE_DF | HAVE_TIME);
+ return new;
+ }
+ }
}
/*
@@ -7636,11 +7937,11 @@ date_to_datetime(VALUE self)
static VALUE
datetime_to_time(VALUE self)
{
- VALUE d, t;
-
- d = copy_obj_with_new_offset(self, 0);
+ volatile VALUE dup = dup_obj_with_new_offset(self, 0);
{
- get_d1(d);
+ VALUE t;
+
+ get_d1(dup);
t = f_utc6(rb_cTime,
m_real_year(dat),
@@ -7663,37 +7964,27 @@ datetime_to_time(VALUE self)
static VALUE
datetime_to_date(VALUE self)
{
- get_d1(self);
+ get_d1a(self);
- if (simple_dat_p(dat))
- return d_simple_new_internal(cDate,
- dat->s.nth,
- m_local_jd(dat),
- dat->s.sg,
- dat->s.year,
-#ifndef USE_PACK
- dat->s.mon,
- dat->s.mday,
-#else
- EX_MON(dat->s.pd),
- EX_MDAY(dat->s.pd),
-#endif
- dat->s.flags);
- else
- return d_simple_new_internal(cDate,
- dat->c.nth,
- m_local_jd(dat),
- dat->c.sg,
- dat->c.year,
-#ifndef USE_PACK
- dat->c.mon,
- dat->c.mday,
-#else
- EX_MON(dat->c.pd),
- EX_MDAY(dat->c.pd),
-#endif
- dat->c.flags &
- ~(HAVE_DF | HAVE_TIME | COMPLEX_DAT));
+ if (simple_dat_p(adat)) {
+ VALUE new = d_lite_s_alloc_simple(cDate);
+ {
+ get_d1b(new);
+ bdat->s = adat->s;
+ bdat->s.jd = m_local_jd(adat);
+ return new;
+ }
+ }
+ else {
+ VALUE new = d_lite_s_alloc_simple(cDate);
+ {
+ get_d1b(new);
+ copy_complex_to_simple(&bdat->s, &adat->c)
+ bdat->s.jd = m_local_jd(adat);
+ bdat->s.flags &= ~(HAVE_DF | HAVE_TIME | COMPLEX_DAT);
+ return new;
+ }
+ }
}
/*
@@ -8192,8 +8483,8 @@ Init_date_core(void)
rb_gc_register_mark_object(unix_epoch_in_ajd);
rb_gc_register_mark_object(day_in_nanoseconds);
- positive_inf = NUM2DBL(rb_const_get(rb_cFloat, rb_intern("INFINITY")));
- negative_inf = -positive_inf;
+ positive_inf = +INFINITY;
+ negative_inf = -INFINITY;
/*
* Class representing a date.
@@ -8307,6 +8598,7 @@ Init_date_core(void)
#ifndef NDEBUG
rb_define_singleton_method(cDate, "new!", date_s_new_bang, -1);
+ rb_define_alias(rb_singleton_class(cDate), "new_l!", "new");
#endif
rb_define_singleton_method(cDate, "jd", date_s_jd, -1);
@@ -8341,11 +8633,14 @@ Init_date_core(void)
rb_define_singleton_method(cDate, "jisx0301", date_s_jisx0301, -1);
#ifndef NDEBUG
- rb_define_method(cDate, "fill", d_lite_fill, 0);
+ rb_define_method(cDate, "initialize", d_lite_initialize, -1);
#endif
-
rb_define_method(cDate, "initialize_copy", d_lite_initialize_copy, 1);
+#ifndef NDEBUG
+ rb_define_method(cDate, "fill", d_lite_fill, 0);
+#endif
+
rb_define_method(cDate, "ajd", d_lite_ajd, 0);
rb_define_method(cDate, "amjd", d_lite_amjd, 0);
rb_define_method(cDate, "jd", d_lite_jd, 0);
@@ -8388,7 +8683,7 @@ Init_date_core(void)
rb_define_method(cDate, "saturday?", d_lite_saturday_p, 0);
#ifndef NDEBUG
- rb_define_method(cDate, "nth_kday?", generic_nth_kday_p, 2);
+ rb_define_method(cDate, "nth_kday?", d_lite_nth_kday_p, 2);
#endif
rb_define_method(cDate, "julian?", d_lite_julian_p, 0);
@@ -8420,9 +8715,9 @@ Init_date_core(void)
rb_define_method(cDate, "next_year", d_lite_next_year, -1);
rb_define_method(cDate, "prev_year", d_lite_prev_year, -1);
- rb_define_method(cDate, "step", generic_step, -1);
- rb_define_method(cDate, "upto", generic_upto, 1);
- rb_define_method(cDate, "downto", generic_downto, 1);
+ rb_define_method(cDate, "step", d_lite_step, -1);
+ rb_define_method(cDate, "upto", d_lite_upto, 1);
+ rb_define_method(cDate, "downto", d_lite_downto, 1);
rb_define_method(cDate, "<=>", d_lite_cmp, 1);
rb_define_method(cDate, "===", d_lite_equal, 1);
@@ -8430,6 +8725,9 @@ Init_date_core(void)
rb_define_method(cDate, "hash", d_lite_hash, 0);
rb_define_method(cDate, "to_s", d_lite_to_s, 0);
+#ifndef NDEBUG
+ rb_define_method(cDate, "inspect_raw", d_lite_inspect_raw, 0);
+#endif
rb_define_method(cDate, "inspect", d_lite_inspect, 0);
rb_define_method(cDate, "strftime", d_lite_strftime, -1);
@@ -8444,6 +8742,9 @@ Init_date_core(void)
rb_define_method(cDate, "httpdate", d_lite_httpdate, 0);
rb_define_method(cDate, "jisx0301", d_lite_jisx0301, 0);
+#ifndef NDEBUG
+ rb_define_method(cDate, "marshal_dump_old", d_lite_marshal_dump_old, 0);
+#endif
rb_define_method(cDate, "marshal_dump", d_lite_marshal_dump, 0);
rb_define_method(cDate, "marshal_load", d_lite_marshal_load, 1);
@@ -8451,8 +8752,6 @@ Init_date_core(void)
cDateTime = rb_define_class("DateTime", cDate);
- rb_undef_method(CLASS_OF(cDateTime), "today");
-
rb_define_singleton_method(cDateTime, "jd", datetime_s_jd, -1);
rb_define_singleton_method(cDateTime, "ordinal", datetime_s_ordinal, -1);
rb_define_singleton_method(cDateTime, "civil", datetime_s_civil, -1);
@@ -8467,6 +8766,8 @@ Init_date_core(void)
datetime_s_nth_kday, -1);
#endif
+ rb_undef_method(CLASS_OF(cDateTime), "today");
+
rb_define_singleton_method(cDateTime, "now", datetime_s_now, -1);
rb_define_singleton_method(cDateTime, "_strptime",
datetime_s__strptime, -1);