diff options
-rw-r--r-- | ChangeLog | 8 | ||||
-rw-r--r-- | ext/date/date_core.c | 477 | ||||
-rw-r--r-- | ext/date/date_strftime.c | 133 | ||||
-rw-r--r-- | ext/date/date_tmx.h | 55 |
4 files changed, 352 insertions, 321 deletions
@@ -1,3 +1,11 @@ +Sun Jun 5 10:06:50 2011 Tadayoshi Funaba <tadf@dotrb.org> + + * ext/date/date_tmx.h: now does not place decoded data. allows to + access indirectly via functions on demand. + * ext/date/date_strftime.c: ditto. + * ext/date/date_core.c: ditto. + * ext/date/date_core.c ({d|dt}_lite_to_s): use strftime. + Sun Jun 5 06:22:02 2011 Tadayoshi Funaba <tadf@dotrb.org> * NEWS: wrote about changes of date. diff --git a/ext/date/date_core.c b/ext/date/date_core.c index 763e059550..5743e74f67 100644 --- a/ext/date/date_core.c +++ b/ext/date/date_core.c @@ -1701,6 +1701,69 @@ m_yday(union DateData *x) return rd; } +static int +m_wday(union DateData *x) +{ + return c_jd_to_wday(m_local_jd(x)); +} + +static VALUE +m_cwyear(union DateData *x) +{ + double sg; + int ry, rw, rd; + VALUE ry2; + + sg = x_sg(x); /* !=m_sg() */ + c_jd_to_commercial(m_local_jd(x), sg, + &ry, &rw, &rd); + encode_year(m_nth(x), ry, sg, &ry2); + return ry2; +} + +static int +m_cweek(union DateData *x) +{ + int ry, rw, rd; + + c_jd_to_commercial(m_local_jd(x), x_sg(x), /* !=m_sg() */ + &ry, &rw, &rd); + return rw; +} + +static int +m_cwday(union DateData *x) +{ + int w; + + w = m_wday(x); + if (w == 0) + w = 7; + return w; +} + +static int +m_wnumx(union DateData *x, int f) +{ + int ry, rw, rd; + + c_jd_to_weeknum(m_local_jd(x), f, x_sg(x), /* !=m_sg() */ + &ry, &rw, &rd); + return rw; +} + +static int +m_wnum0(union DateData *x) +{ + return m_wnumx(x, 0); +} + +static int +m_wnum1(union DateData *x) +{ + return m_wnumx(x, 1); +} + inline static int m_hour(union DateData *x) { @@ -1746,12 +1809,6 @@ m_sec(union DateData *x) } } -static int -m_wday(union DateData *x) -{ - return c_jd_to_wday(m_local_jd(x)); -} - #define decode_offset(of,s,h,m)\ {\ int a;\ @@ -4648,109 +4705,6 @@ d_lite_day_fraction(VALUE self) return m_fr(dat); } -static VALUE -d_lite_wnum0(VALUE self) -{ - int ry, rw, rd; - - get_d1(self); - c_jd_to_weeknum(m_local_jd(dat), 0, x_sg(dat), /* !=m_sg() */ - &ry, &rw, &rd); - return INT2FIX(rw); -} - -static VALUE -d_lite_wnum1(VALUE self) -{ - int ry, rw, rd; - - get_d1(self); - c_jd_to_weeknum(m_local_jd(dat), 1, x_sg(dat), /* !=m_sg() */ - &ry, &rw, &rd); - return INT2FIX(rw); -} - -/* - * call-seq: - * d.hour - * - * Get the hour of this date. - */ -static VALUE -d_lite_hour(VALUE self) -{ - get_d1(self); - return INT2FIX(m_hour(dat)); -} - -/* - * call-seq: - * d.min - * d.minute - * - * Get the minute of this date. - */ -static VALUE -d_lite_min(VALUE self) -{ - get_d1(self); - return INT2FIX(m_min(dat)); -} - -/* - * call-seq: - * d.sec - * d.second - * - * Get the second of this date. - */ -static VALUE -d_lite_sec(VALUE self) -{ - get_d1(self); - return INT2FIX(m_sec(dat)); -} - -/* - * call-seq: - * d.sec_fraction - * d.second_fraction - * - * Get the fraction-of-a-second of this date. - */ -static VALUE -d_lite_sec_fraction(VALUE self) -{ - get_d1(self); - return m_sf_in_sec(dat); -} - -/* - * call-seq: - * d.offset - * - * Get the offset of this date. - */ -static VALUE -d_lite_offset(VALUE self) -{ - get_d1(self); - return m_of_in_day(dat); -} - -/* - * call-seq: - * d.zone - * - * Get the zone name of this date. - */ -static VALUE -d_lite_zone(VALUE self) -{ - get_d1(self); - return m_zone(dat); -} - /* * call-seq: * d.cwyear @@ -4761,16 +4715,8 @@ d_lite_zone(VALUE self) static VALUE d_lite_cwyear(VALUE self) { - double sg; - int ry, rw, rd; - VALUE ry2; - get_d1(self); - sg = x_sg(dat); /* !=m_sg() */ - c_jd_to_commercial(m_local_jd(dat), sg, - &ry, &rw, &rd); - encode_year(m_nth(dat), ry, sg, &ry2); - return ry2; + return m_cwyear(dat); } /* @@ -4782,12 +4728,8 @@ d_lite_cwyear(VALUE self) static VALUE d_lite_cweek(VALUE self) { - int ry, rw, rd; - get_d1(self); - c_jd_to_commercial(m_local_jd(dat), x_sg(dat), /* !=m_sg() */ - &ry, &rw, &rd); - return INT2FIX(rw); + return INT2FIX(m_cweek(dat)); } /* @@ -4800,13 +4742,22 @@ d_lite_cweek(VALUE self) static VALUE d_lite_cwday(VALUE self) { - int w; + get_d1(self); + return INT2FIX(m_cwday(dat)); +} +static VALUE +d_lite_wnum0(VALUE self) +{ get_d1(self); - w = m_wday(dat); - if (w == 0) - w = 7; - return INT2FIX(w); + return INT2FIX(m_wnum0(dat)); +} + +static VALUE +d_lite_wnum1(VALUE self) +{ + get_d1(self); + return INT2FIX(m_wnum1(dat)); } /* @@ -4936,6 +4887,87 @@ d_lite_nth_kday_p(VALUE self, VALUE n, VALUE k) /* * call-seq: + * d.hour + * + * Get the hour of this date. + */ +static VALUE +d_lite_hour(VALUE self) +{ + get_d1(self); + return INT2FIX(m_hour(dat)); +} + +/* + * call-seq: + * d.min + * d.minute + * + * Get the minute of this date. + */ +static VALUE +d_lite_min(VALUE self) +{ + get_d1(self); + return INT2FIX(m_min(dat)); +} + +/* + * call-seq: + * d.sec + * d.second + * + * Get the second of this date. + */ +static VALUE +d_lite_sec(VALUE self) +{ + get_d1(self); + return INT2FIX(m_sec(dat)); +} + +/* + * call-seq: + * d.sec_fraction + * d.second_fraction + * + * Get the fraction-of-a-second of this date. + */ +static VALUE +d_lite_sec_fraction(VALUE self) +{ + get_d1(self); + return m_sf_in_sec(dat); +} + +/* + * call-seq: + * d.offset + * + * Get the offset of this date. + */ +static VALUE +d_lite_offset(VALUE self) +{ + get_d1(self); + return m_of_in_day(dat); +} + +/* + * call-seq: + * d.zone + * + * Get the zone name of this date. + */ +static VALUE +d_lite_zone(VALUE self) +{ + get_d1(self); + return m_zone(dat); +} + +/* + * call-seq: * d.julian? * * Is the current date old-style (Julian Calendar)? @@ -6192,8 +6224,10 @@ d_lite_hash(VALUE self) return LONG2FIX(v); } -#define AVOID_SPRINTF_BUG -#define FMT_TO_S "%.4d-%02d-%02d" +#include "date_tmx.h" +static void set_tmx(VALUE, struct tmx *); +static VALUE strftimev(const char *, VALUE, + void (*)(VALUE, struct tmx *)); /* * call-seq: @@ -6204,24 +6238,7 @@ d_lite_hash(VALUE self) static VALUE d_lite_to_s(VALUE self) { - get_d1(self); - - 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(FMT_TO_S); - argv[1] = m_real_year(dat); - argv[2] = INT2FIX(m_mon(dat)); - argv[3] = INT2FIX(m_mday(dat)); - return rb_f_sprintf(4, argv); - } + return strftimev("%Y-%m-%d", self, set_tmx); } #ifndef NDEBUG @@ -6316,9 +6333,8 @@ d_lite_inspect(VALUE self) #include <errno.h> #include "date_tmx.h" -size_t -date_strftime(char *s, size_t maxsize, const char *format, - const struct tmx *tmx); +size_t date_strftime(char *s, size_t maxsize, const char *format, + const struct tmx *tmx); #define SMALLBUF 100 static size_t @@ -6352,35 +6368,54 @@ date_strftime_alloc(char **buf, const char *format, return len; } -static void -d_lite_set_tmx(VALUE self, struct tmx *tmx) +static VALUE +tmx_m_of(union DateData *x) { - get_d1(self); + return INT2FIX(m_of(x)); +} - tmx->year = m_real_year(dat); - tmx->yday = m_yday(dat); - tmx->mon = m_mon(dat); - tmx->mday = m_mday(dat); - tmx->wday = m_wday(dat); +static char * +tmx_m_zone(union DateData *x) +{ + return RSTRING_PTR(m_zone(x)); +} - if (simple_dat_p(dat)) { - tmx->hour = 0; - tmx->min = 0; - tmx->sec = 0; - tmx->offset = INT2FIX(0); - tmx->zone = "+00:00"; - tmx->timev = day_to_sec(f_sub(m_real_jd(dat), - UNIX_EPOCH_IN_CJD)); - } - else { - tmx->hour = m_hour(dat); - tmx->min = m_min(dat); - tmx->sec = m_sec(dat); - tmx->offset = INT2FIX(m_of(dat)); - tmx->zone = RSTRING_PTR(m_zone(dat)); - tmx->timev = day_to_sec(f_sub(m_ajd(dat), - UNIX_EPOCH_IN_AJD)); - } +static VALUE +tmx_m_timev(union DateData *x) +{ + if (simple_dat_p(x)) + return day_to_sec(f_sub(m_real_jd(x), + UNIX_EPOCH_IN_CJD)); + else + return day_to_sec(f_sub(m_ajd(x), + UNIX_EPOCH_IN_AJD)); +} + +static struct tmx_funcs tmx_funcs = { + (VALUE (*)(void *))m_real_year, + (int (*)(void *))m_yday, + (int (*)(void *))m_mon, + (int (*)(void *))m_mday, + (VALUE (*)(void *))m_cwyear, + (int (*)(void *))m_cweek, + (int (*)(void *))m_cwday, + (int (*)(void *))m_wnum0, + (int (*)(void *))m_wnum1, + (int (*)(void *))m_wday, + (int (*)(void *))m_hour, + (int (*)(void *))m_min, + (int (*)(void *))m_sec, + (VALUE (*)(void *))tmx_m_of, + (char *(*)(void *))tmx_m_zone, + (VALUE (*)(void *))tmx_m_timev +}; + +static void +set_tmx(VALUE self, struct tmx *tmx) +{ + get_d1(self); + tmx->dat = (void *)dat; + tmx->funcs = &tmx_funcs; } static VALUE @@ -6449,7 +6484,7 @@ static VALUE d_lite_strftime(int argc, VALUE *argv, VALUE self) { return date_strftime_internal(argc, argv, self, - "%F", d_lite_set_tmx); + "%F", set_tmx); } static VALUE @@ -6479,7 +6514,7 @@ strftimev(const char *fmt, VALUE self, static VALUE d_lite_asctime(VALUE self) { - return strftimev("%c", self, d_lite_set_tmx); + return strftimev("%c", self, set_tmx); } /* @@ -6492,7 +6527,7 @@ d_lite_asctime(VALUE self) static VALUE d_lite_iso8601(VALUE self) { - return strftimev("%F", self, d_lite_set_tmx); + return strftimev("%F", self, set_tmx); } /* @@ -6504,7 +6539,7 @@ d_lite_iso8601(VALUE self) static VALUE d_lite_rfc3339(VALUE self) { - return strftimev("%FT%T%:z", self, d_lite_set_tmx); + return strftimev("%FT%T%:z", self, set_tmx); } /* @@ -6517,7 +6552,7 @@ d_lite_rfc3339(VALUE self) static VALUE d_lite_rfc2822(VALUE self) { - return strftimev("%a, %-d %b %Y %T %z", self, d_lite_set_tmx); + return strftimev("%a, %-d %b %Y %T %z", self, set_tmx); } /* @@ -6531,7 +6566,7 @@ static VALUE d_lite_httpdate(VALUE self) { volatile VALUE dup = dup_obj_with_new_offset(self, 0); - return strftimev("%a, %d %b %Y %T GMT", dup, d_lite_set_tmx); + return strftimev("%a, %d %b %Y %T GMT", dup, set_tmx); } static VALUE @@ -6574,9 +6609,9 @@ d_lite_jisx0301(VALUE self) if (!gengo(m_real_local_jd(dat), m_real_year(dat), argv)) - return strftimev("%F", self, d_lite_set_tmx); + return strftimev("%F", self, set_tmx); return f_add(rb_f_sprintf(2, argv), - strftimev(".%m.%d", self, d_lite_set_tmx)); + strftimev(".%m.%d", self, set_tmx)); } #ifndef NDEBUG @@ -7618,9 +7653,6 @@ 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 @@ -7630,38 +7662,7 @@ datetime_s_jisx0301(int argc, VALUE *argv, VALUE klass) static VALUE dt_lite_to_s(VALUE self) { - get_d1(self); - - 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(), FMT_TO_S, - m_year(dat), m_mon(dat), m_mday(dat), - m_hour(dat), m_min(dat), m_sec(dat), - s, h, m); - } - else { - int s, h, m; - VALUE argv[10]; - - decode_offset(m_of(dat), s, h, m); - 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)); - argv[4] = INT2FIX(m_hour(dat)); - argv[5] = INT2FIX(m_min(dat)); - argv[6] = INT2FIX(m_sec(dat)); - argv[7] = INT2FIX(s); - argv[8] = INT2FIX(h); - argv[9] = INT2FIX(m); - return rb_f_sprintf(10, argv); - } + return strftimev("%Y-%m-%dT%H:%M:%S%:z", self, set_tmx); } /* @@ -7674,7 +7675,7 @@ static VALUE dt_lite_strftime(int argc, VALUE *argv, VALUE self) { return date_strftime_internal(argc, argv, self, - "%FT%T%:z", d_lite_set_tmx); + "%FT%T%:z", set_tmx); } static VALUE @@ -7699,7 +7700,7 @@ dt_lite_iso8601_timediv(VALUE self, VALUE n) fmt = f_add3(rb_usascii_str_new2("T%T"), f, rb_usascii_str_new2("%:z")); - return strftimev(RSTRING_PTR(fmt), self, d_lite_set_tmx); + return strftimev(RSTRING_PTR(fmt), self, set_tmx); } /* @@ -7720,7 +7721,7 @@ dt_lite_iso8601(int argc, VALUE *argv, VALUE self) if (argc < 1) n = INT2FIX(0); - return f_add(strftimev("%F", self, d_lite_set_tmx), + return f_add(strftimev("%F", self, set_tmx), dt_lite_iso8601_timediv(self, n)); } @@ -7759,10 +7760,10 @@ dt_lite_jisx0301(int argc, VALUE *argv, VALUE self) if (!gengo(m_real_local_jd(dat), m_real_year(dat), argv2)) - return f_add(strftimev("%F", self, d_lite_set_tmx), + return f_add(strftimev("%F", self, set_tmx), dt_lite_iso8601_timediv(self, n)); return f_add(f_add(rb_f_sprintf(2, argv2), - strftimev(".%m.%d", self, d_lite_set_tmx)), + strftimev(".%m.%d", self, set_tmx)), dt_lite_iso8601_timediv(self, n)); } } @@ -8655,23 +8656,13 @@ Init_date_core(void) rb_define_method(cDate, "day", d_lite_mday, 0); rb_define_method(cDate, "day_fraction", d_lite_day_fraction, 0); - rb_define_private_method(cDate, "wnum0", d_lite_wnum0, 0); - rb_define_private_method(cDate, "wnum1", d_lite_wnum1, 0); - - rb_define_private_method(cDate, "hour", d_lite_hour, 0); - rb_define_private_method(cDate, "min", d_lite_min, 0); - rb_define_private_method(cDate, "minute", d_lite_min, 0); - rb_define_private_method(cDate, "sec", d_lite_sec, 0); - rb_define_private_method(cDate, "second", d_lite_sec, 0); - rb_define_private_method(cDate, "sec_fraction", d_lite_sec_fraction, 0); - rb_define_private_method(cDate, "second_fraction", d_lite_sec_fraction, 0); - rb_define_private_method(cDate, "offset", d_lite_offset, 0); - rb_define_private_method(cDate, "zone", d_lite_zone, 0); - rb_define_method(cDate, "cwyear", d_lite_cwyear, 0); rb_define_method(cDate, "cweek", d_lite_cweek, 0); rb_define_method(cDate, "cwday", d_lite_cwday, 0); + rb_define_private_method(cDate, "wnum0", d_lite_wnum0, 0); + rb_define_private_method(cDate, "wnum1", d_lite_wnum1, 0); + rb_define_method(cDate, "wday", d_lite_wday, 0); rb_define_method(cDate, "sunday?", d_lite_sunday_p, 0); @@ -8686,6 +8677,16 @@ Init_date_core(void) rb_define_method(cDate, "nth_kday?", d_lite_nth_kday_p, 2); #endif + rb_define_private_method(cDate, "hour", d_lite_hour, 0); + rb_define_private_method(cDate, "min", d_lite_min, 0); + rb_define_private_method(cDate, "minute", d_lite_min, 0); + rb_define_private_method(cDate, "sec", d_lite_sec, 0); + rb_define_private_method(cDate, "second", d_lite_sec, 0); + rb_define_private_method(cDate, "sec_fraction", d_lite_sec_fraction, 0); + rb_define_private_method(cDate, "second_fraction", d_lite_sec_fraction, 0); + rb_define_private_method(cDate, "offset", d_lite_offset, 0); + rb_define_private_method(cDate, "zone", d_lite_zone, 0); + rb_define_method(cDate, "julian?", d_lite_julian_p, 0); rb_define_method(cDate, "gregorian?", d_lite_gregorian_p, 0); rb_define_method(cDate, "leap?", d_lite_leap_p, 0); diff --git a/ext/date/date_strftime.c b/ext/date/date_strftime.c index 0820a26d9b..6525209d56 100644 --- a/ext/date/date_strftime.c +++ b/ext/date/date_strftime.c @@ -97,6 +97,7 @@ #undef strchr /* avoid AIX weirdness */ +#if 0 #if !defined __STDC__ && !defined _WIN32 #define const /**/ static int weeknumber(); @@ -109,6 +110,7 @@ adddecl(static int iso8601wknum(const struct tm *timeptr);) static int weeknumber_v(const struct tmx *tmx, int firstweekday); adddecl(static int iso8601wknum_v(const struct tmx *tmx);) #endif +#endif #ifdef STDC_HEADERS #include <stdlib.h> @@ -298,10 +300,10 @@ date_strftime_with_tmx(char *s, size_t maxsize, const char *format, flags &= ~(BIT_OF(LOWER)|BIT_OF(CHCASE)); flags |= BIT_OF(UPPER); } - if (tmx->wday < 0 || tmx->wday > 6) + if (tmx_wday < 0 || tmx_wday > 6) i = 1, tp = "?"; else - i = 3, tp = days_l[tmx->wday]; + i = 3, tp = days_l[tmx_wday]; break; case 'A': /* full weekday name */ @@ -309,10 +311,10 @@ date_strftime_with_tmx(char *s, size_t maxsize, const char *format, flags &= ~(BIT_OF(LOWER)|BIT_OF(CHCASE)); flags |= BIT_OF(UPPER); } - if (tmx->wday < 0 || tmx->wday > 6) + if (tmx_wday < 0 || tmx_wday > 6) i = 1, tp = "?"; else - i = strlen(tp = days_l[tmx->wday]); + i = strlen(tp = days_l[tmx_wday]); break; #ifdef SYSV_EXT @@ -323,10 +325,10 @@ date_strftime_with_tmx(char *s, size_t maxsize, const char *format, flags &= ~(BIT_OF(LOWER)|BIT_OF(CHCASE)); flags |= BIT_OF(UPPER); } - if (tmx->mon < 1 || tmx->mon > 12) + if (tmx_mon < 1 || tmx_mon > 12) i = 1, tp = "?"; else - i = 3, tp = months_l[tmx->mon-1]; + i = 3, tp = months_l[tmx_mon-1]; break; case 'B': /* full month name */ @@ -334,10 +336,10 @@ date_strftime_with_tmx(char *s, size_t maxsize, const char *format, flags &= ~(BIT_OF(LOWER)|BIT_OF(CHCASE)); flags |= BIT_OF(UPPER); } - if (tmx->mon < 1 || tmx->mon > 12) + if (tmx_mon < 1 || tmx_mon > 12) i = 1, tp = "?"; else - i = strlen(tp = months_l[tmx->mon-1]); + i = strlen(tp = months_l[tmx_mon-1]); break; case 'c': /* appropriate date and time representation */ @@ -345,17 +347,17 @@ date_strftime_with_tmx(char *s, size_t maxsize, const char *format, continue; case 'd': /* day of the month, 01 - 31 */ - i = range(1, tmx->mday, 31); + i = range(1, tmx_mday, 31); FMT('0', 2, "d", (int)i); continue; case 'H': /* hour, 24-hour clock, 00 - 23 */ - i = range(0, tmx->hour, 23); + i = range(0, tmx_hour, 23); FMT('0', 2, "d", (int)i); continue; case 'I': /* hour, 12-hour clock, 01 - 12 */ - i = range(0, tmx->hour, 23); + i = range(0, tmx_hour, 23); if (i == 0) i = 12; else if (i > 12) @@ -364,16 +366,16 @@ date_strftime_with_tmx(char *s, size_t maxsize, const char *format, continue; case 'j': /* day of the year, 001 - 366 */ - FMT('0', 3, "d", tmx->yday); + FMT('0', 3, "d", tmx_yday); continue; case 'm': /* month, 01 - 12 */ - i = range(1, tmx->mon, 12); + i = range(1, tmx_mon, 12); FMT('0', 2, "d", (int)i); continue; case 'M': /* minute, 00 - 59 */ - i = range(0, tmx->min, 59); + i = range(0, tmx_min, 59); FMT('0', 2, "d", (int)i); continue; @@ -384,7 +386,7 @@ date_strftime_with_tmx(char *s, size_t maxsize, const char *format, flags &= ~(BIT_OF(UPPER)|BIT_OF(CHCASE)); flags |= BIT_OF(LOWER); } - i = range(0, tmx->hour, 23); + i = range(0, tmx_hour, 23); if (i < 12) tp = ampm[0]; else @@ -394,14 +396,14 @@ date_strftime_with_tmx(char *s, size_t maxsize, const char *format, case 's': { - VALUE sec = div(tmx->timev, INT2FIX(1)); + VALUE sec = div(tmx_timev, INT2FIX(1)); FMTV('0', 1, "d", sec); } continue; case 'Q': { - VALUE sec = div(tmx->timev, + VALUE sec = div(tmx_timev, rb_rational_new2(INT2FIX(1), INT2FIX(1000))); FMTV('0', 1, "d", sec); @@ -409,21 +411,21 @@ date_strftime_with_tmx(char *s, size_t maxsize, const char *format, continue; case 'S': /* second, 00 - 60 */ - i = range(0, tmx->sec, 60); + i = range(0, tmx_sec, 60); FMT('0', 2, "d", (int)i); continue; case 'U': /* week of year, Sunday is first day of week */ - FMT('0', 2, "d", weeknumber_v(tmx, 0)); + FMT('0', 2, "d", tmx_wnum0); continue; case 'w': /* weekday, Sunday == 0, 0 - 6 */ - i = range(0, tmx->wday, 6); + i = range(0, tmx_wday, 6); FMT('0', 1, "d", (int)i); continue; case 'W': /* week of year, Monday is first day of week */ - FMT('0', 2, "d", weeknumber_v(tmx, 1)); + FMT('0', 2, "d", tmx_wnum1); continue; case 'x': /* appropriate date representation */ @@ -435,17 +437,17 @@ date_strftime_with_tmx(char *s, size_t maxsize, const char *format, continue; case 'y': /* year without a century, 00 - 99 */ - i = NUM2INT(mod(tmx->year, INT2FIX(100))); + i = NUM2INT(mod(tmx_year, INT2FIX(100))); FMT('0', 2, "d", (int)i); continue; case 'Y': /* year with century */ - if (FIXNUM_P(tmx->year)) { - long y = FIX2LONG(tmx->year); + if (FIXNUM_P(tmx_year)) { + long y = FIX2LONG(tmx_year); FMT('0', 0 <= y ? 4 : 5, "ld", y); } else { - FMTV('0', 4, "d", tmx->year); + FMTV('0', 4, "d", tmx_year); } continue; @@ -455,7 +457,7 @@ date_strftime_with_tmx(char *s, size_t maxsize, const char *format, long aoff; int hl, hw; - off = NUM2LONG(rb_funcall(tmx->offset, rb_intern("round"), 0)); + off = NUM2LONG(rb_funcall(tmx_offset, rb_intern("round"), 0)); aoff = off; if (aoff < 0) @@ -547,10 +549,10 @@ date_strftime_with_tmx(char *s, size_t maxsize, const char *format, flags &= ~(BIT_OF(UPPER)|BIT_OF(CHCASE)); flags |= BIT_OF(LOWER); } - if (tmx->zone == NULL) + if (tmx_zone == NULL) tp = ""; else - tp = tmx->zone; + tp = tmx_zone; i = strlen(tp); break; @@ -570,7 +572,7 @@ date_strftime_with_tmx(char *s, size_t maxsize, const char *format, continue; case 'e': /* day of month, blank padded */ - FMT(' ', 2, "d", range(1, tmx->mday, 31)); + FMT(' ', 2, "d", range(1, tmx_mday, 31)); continue; case 'r': /* time as %I:%M:%S %p */ @@ -588,12 +590,12 @@ date_strftime_with_tmx(char *s, size_t maxsize, const char *format, #ifdef SUNOS_EXT case 'k': /* hour, 24-hour clock, blank pad */ - i = range(0, tmx->hour, 23); + i = range(0, tmx_hour, 23); FMT(' ', 2, "d", (int)i); continue; case 'l': /* hour, 12-hour clock, 1 - 12, blank pad */ - i = range(0, tmx->hour, 23); + i = range(0, tmx_hour, 23); if (i == 0) i = 12; else if (i > 12) @@ -610,7 +612,7 @@ date_strftime_with_tmx(char *s, size_t maxsize, const char *format, #ifdef POSIX2_DATE case 'C': - FMTV('0', 2, "d", div(tmx->year, INT2FIX(100))); + FMTV('0', 2, "d", div(tmx_year, INT2FIX(100))); continue; case 'E': @@ -627,51 +629,36 @@ date_strftime_with_tmx(char *s, size_t maxsize, const char *format, goto again; goto unknown; case 'V': /* week of year according ISO 8601 */ - FMT('0', 2, "d", iso8601wknum_v(tmx)); + FMT('0', 2, "d", tmx_cweek); continue; case 'u': /* ISO 8601: Weekday as a decimal number [1 (Monday) - 7] */ - FMT('0', 1, "d", tmx->wday == 0 ? 7 : tmx->wday); + FMT('0', 1, "d", tmx_cwday); continue; #endif /* POSIX2_DATE */ #ifdef ISO_DATE_EXT case 'G': case 'g': - /* - * Year of ISO week. - * - * If it's December but the ISO week number is one, - * that week is in next year. - * If it's January but the ISO week number is 52 or - * 53, that week is in last year. - * Otherwise, it's this year. - */ - { - VALUE yv = tmx->year; - w = iso8601wknum_v(tmx); - if (tmx->mon == 12 && w == 1) - yv = add(yv, INT2FIX(1)); - else if (tmx->mon == 1 && w >= 52) - yv = sub(yv, INT2FIX(1)); - + { + VALUE yv = tmx_cwyear; if (*format == 'G') { - if (FIXNUM_P(yv)) { - long y = FIX2LONG(yv); - FMT('0', 0 <= y ? 4 : 5, "ld", y); - } - else { - FMTV('0', 4, "d", yv); - } - } + if (FIXNUM_P(yv)) { + long y = FIX2LONG(yv); + FMT('0', 0 <= y ? 4 : 5, "ld", y); + } + else { + FMTV('0', 4, "d", yv); + } + } else { yv = mod(yv, INT2FIX(100)); y = FIX2LONG(yv); FMT('0', 2, "ld", y); } continue; - } + } #endif /* ISO_DATE_EXT */ @@ -696,7 +683,7 @@ date_strftime_with_tmx(char *s, size_t maxsize, const char *format, NEEDS(precision); { - VALUE subsec = mod(tmx->timev, INT2FIX(1)); + VALUE subsec = mod(tmx_timev, INT2FIX(1)); int ww; long n; @@ -817,6 +804,7 @@ date_strftime(char *s, size_t maxsize, const char *format, return date_strftime_with_tmx(s, maxsize, format, tmx); } +#if 0 /* isleap --- is a year a leap year? */ #ifndef __STDC__ @@ -837,21 +825,21 @@ tmx2tm_noyear(const struct tmx *tmx, struct tm *result) struct tm tm; /* for isleap() in iso8601wknum. +100 is -1900 (mod 400). */ - tm.tm_year = FIX2INT(mod(tmx->year, INT2FIX(400))) + 100; - - tm.tm_mon = tmx->mon-1; - tm.tm_mday = tmx->mday; - tm.tm_hour = tmx->hour; - tm.tm_min = tmx->min; - tm.tm_sec = tmx->sec; - tm.tm_wday = tmx->wday; - tm.tm_yday = tmx->yday-1; + tm.tm_year = FIX2INT(mod(tmx_year, INT2FIX(400))) + 100; + + tm.tm_mon = tmx_mon-1; + tm.tm_mday = tmx_mday; + tm.tm_hour = tmx_hour; + tm.tm_min = tmx_min; + tm.tm_sec = tmx_sec; + tm.tm_wday = tmx_wday; + tm.tm_yday = tmx_yday-1; tm.tm_isdst = 0; #if defined(HAVE_STRUCT_TM_TM_GMTOFF) - tm.tm_gmtoff = NUM2LONG(tmx->offset); + tm.tm_gmtoff = NUM2LONG(tmx_offset); #endif #if defined(HAVE_TM_ZONE) - tm.tm_zone = (char *)tmx->zone; + tm.tm_zone = (char *)tmx_zone; #endif *result = tm; } @@ -1018,6 +1006,7 @@ weeknumber_v(const struct tmx *tmx, int firstweekday) tmx2tm_noyear(tmx, &tm); return weeknumber(&tm, firstweekday); } +#endif #if 0 /* ADR --- I'm loathe to mess with ado's code ... */ diff --git a/ext/date/date_tmx.h b/ext/date/date_tmx.h index cdb5b0ddad..2bdb80c316 100644 --- a/ext/date/date_tmx.h +++ b/ext/date/date_tmx.h @@ -1,17 +1,50 @@ +#ifndef DATE_TMX_H +#define DATE_TMX_H + +struct tmx_funcs { + VALUE (*year)(void *dat); + int (*yday)(void *dat); + int (*mon)(void *dat); + int (*mday)(void *dat); + VALUE (*cwyear)(void *dat); + int (*cweek)(void *dat); + int (*cwday)(void *dat); + int (*wnum0)(void *dat); + int (*wnum1)(void *dat); + int (*wday)(void *dat); + int (*hour)(void *dat); + int (*min)(void *dat); + int (*sec)(void *dat); + VALUE (*offset)(void *dat); + char *(*zone)(void *dat); + VALUE (*timev)(void *dat); +}; struct tmx { - VALUE year; - int yday; - int mon; - int mday; - int hour; - int min; - int sec; - int wday; - VALUE offset; - const char *zone; - VALUE timev; + void *dat; + struct tmx_funcs *funcs; }; +#define tmx_attr(x) (tmx->funcs->x)(tmx->dat) + +#define tmx_year tmx_attr(year) +#define tmx_yday tmx_attr(yday) +#define tmx_mon tmx_attr(mon) +#define tmx_mday tmx_attr(mday) +#define tmx_cwyear tmx_attr(cwyear) +#define tmx_cweek tmx_attr(cweek) +#define tmx_cwday tmx_attr(cwday) +#define tmx_wnum0 tmx_attr(wnum0) +#define tmx_wnum1 tmx_attr(wnum1) +#define tmx_wday tmx_attr(wday) +#define tmx_hour tmx_attr(hour) +#define tmx_min tmx_attr(min) +#define tmx_sec tmx_attr(sec) +#define tmx_offset tmx_attr(offset) +#define tmx_zone tmx_attr(zone) +#define tmx_timev tmx_attr(timev) + +#endif + /* Local variables: c-file-style: "ruby" |