1
0
Fork 0
mirror of https://github.com/ruby/ruby.git synced 2022-11-09 12:17:21 -05:00

* 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.



git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@31923 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
This commit is contained in:
tadf 2011-06-05 01:13:19 +00:00
parent 2473b2ceaf
commit a975bf245f
4 changed files with 353 additions and 322 deletions

View file

@ -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> Sun Jun 5 06:22:02 2011 Tadayoshi Funaba <tadf@dotrb.org>
* NEWS: wrote about changes of date. * NEWS: wrote about changes of date.

View file

@ -1701,6 +1701,69 @@ m_yday(union DateData *x)
return rd; 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 inline static int
m_hour(union DateData *x) 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)\ #define decode_offset(of,s,h,m)\
{\ {\
int a;\ int a;\
@ -4648,109 +4705,6 @@ d_lite_day_fraction(VALUE self)
return m_fr(dat); 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: * call-seq:
* d.cwyear * d.cwyear
@ -4761,16 +4715,8 @@ d_lite_zone(VALUE self)
static VALUE static VALUE
d_lite_cwyear(VALUE self) d_lite_cwyear(VALUE self)
{ {
double sg;
int ry, rw, rd;
VALUE ry2;
get_d1(self); get_d1(self);
sg = x_sg(dat); /* !=m_sg() */ return m_cwyear(dat);
c_jd_to_commercial(m_local_jd(dat), sg,
&ry, &rw, &rd);
encode_year(m_nth(dat), ry, sg, &ry2);
return ry2;
} }
/* /*
@ -4782,12 +4728,8 @@ d_lite_cwyear(VALUE self)
static VALUE static VALUE
d_lite_cweek(VALUE self) d_lite_cweek(VALUE self)
{ {
int ry, rw, rd;
get_d1(self); get_d1(self);
c_jd_to_commercial(m_local_jd(dat), x_sg(dat), /* !=m_sg() */ return INT2FIX(m_cweek(dat));
&ry, &rw, &rd);
return INT2FIX(rw);
} }
/* /*
@ -4800,13 +4742,22 @@ d_lite_cweek(VALUE self)
static VALUE static VALUE
d_lite_cwday(VALUE self) d_lite_cwday(VALUE self)
{ {
int w;
get_d1(self); get_d1(self);
w = m_wday(dat); return INT2FIX(m_cwday(dat));
if (w == 0) }
w = 7;
return INT2FIX(w); static VALUE
d_lite_wnum0(VALUE self)
{
get_d1(self);
return INT2FIX(m_wnum0(dat));
}
static VALUE
d_lite_wnum1(VALUE self)
{
get_d1(self);
return INT2FIX(m_wnum1(dat));
} }
/* /*
@ -4934,6 +4885,87 @@ d_lite_nth_kday_p(VALUE self, VALUE n, VALUE k)
} }
#endif #endif
/*
* 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: * call-seq:
* d.julian? * d.julian?
@ -6192,8 +6224,10 @@ d_lite_hash(VALUE self)
return LONG2FIX(v); return LONG2FIX(v);
} }
#define AVOID_SPRINTF_BUG #include "date_tmx.h"
#define FMT_TO_S "%.4d-%02d-%02d" static void set_tmx(VALUE, struct tmx *);
static VALUE strftimev(const char *, VALUE,
void (*)(VALUE, struct tmx *));
/* /*
* call-seq: * call-seq:
@ -6204,24 +6238,7 @@ d_lite_hash(VALUE self)
static VALUE static VALUE
d_lite_to_s(VALUE self) d_lite_to_s(VALUE self)
{ {
get_d1(self); return strftimev("%Y-%m-%d", self, set_tmx);
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);
}
} }
#ifndef NDEBUG #ifndef NDEBUG
@ -6316,9 +6333,8 @@ d_lite_inspect(VALUE self)
#include <errno.h> #include <errno.h>
#include "date_tmx.h" #include "date_tmx.h"
size_t size_t date_strftime(char *s, size_t maxsize, const char *format,
date_strftime(char *s, size_t maxsize, const char *format, const struct tmx *tmx);
const struct tmx *tmx);
#define SMALLBUF 100 #define SMALLBUF 100
static size_t static size_t
@ -6352,35 +6368,54 @@ date_strftime_alloc(char **buf, const char *format,
return len; return len;
} }
static VALUE
tmx_m_of(union DateData *x)
{
return INT2FIX(m_of(x));
}
static char *
tmx_m_zone(union DateData *x)
{
return RSTRING_PTR(m_zone(x));
}
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 static void
d_lite_set_tmx(VALUE self, struct tmx *tmx) set_tmx(VALUE self, struct tmx *tmx)
{ {
get_d1(self); get_d1(self);
tmx->dat = (void *)dat;
tmx->year = m_real_year(dat); tmx->funcs = &tmx_funcs;
tmx->yday = m_yday(dat);
tmx->mon = m_mon(dat);
tmx->mday = m_mday(dat);
tmx->wday = m_wday(dat);
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 static VALUE
@ -6449,7 +6484,7 @@ static VALUE
d_lite_strftime(int argc, VALUE *argv, VALUE self) d_lite_strftime(int argc, VALUE *argv, VALUE self)
{ {
return date_strftime_internal(argc, argv, self, return date_strftime_internal(argc, argv, self,
"%F", d_lite_set_tmx); "%F", set_tmx);
} }
static VALUE static VALUE
@ -6479,7 +6514,7 @@ strftimev(const char *fmt, VALUE self,
static VALUE static VALUE
d_lite_asctime(VALUE self) 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 static VALUE
d_lite_iso8601(VALUE self) 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 static VALUE
d_lite_rfc3339(VALUE self) 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 static VALUE
d_lite_rfc2822(VALUE self) 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) d_lite_httpdate(VALUE self)
{ {
volatile VALUE dup = dup_obj_with_new_offset(self, 0); 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 static VALUE
@ -6574,9 +6609,9 @@ d_lite_jisx0301(VALUE self)
if (!gengo(m_real_local_jd(dat), if (!gengo(m_real_local_jd(dat),
m_real_year(dat), m_real_year(dat),
argv)) argv))
return strftimev("%F", self, d_lite_set_tmx); return strftimev("%F", self, set_tmx);
return f_add(rb_f_sprintf(2, argv), return f_add(rb_f_sprintf(2, argv),
strftimev(".%m.%d", self, d_lite_set_tmx)); strftimev(".%m.%d", self, set_tmx));
} }
#ifndef NDEBUG #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: * call-seq:
* dt.to_s * dt.to_s
@ -7630,38 +7662,7 @@ datetime_s_jisx0301(int argc, VALUE *argv, VALUE klass)
static VALUE static VALUE
dt_lite_to_s(VALUE self) dt_lite_to_s(VALUE self)
{ {
get_d1(self); return strftimev("%Y-%m-%dT%H:%M:%S%:z", self, set_tmx);
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);
}
} }
/* /*
@ -7674,7 +7675,7 @@ static VALUE
dt_lite_strftime(int argc, VALUE *argv, VALUE self) dt_lite_strftime(int argc, VALUE *argv, VALUE self)
{ {
return date_strftime_internal(argc, argv, self, return date_strftime_internal(argc, argv, self,
"%FT%T%:z", d_lite_set_tmx); "%FT%T%:z", set_tmx);
} }
static VALUE static VALUE
@ -7699,7 +7700,7 @@ dt_lite_iso8601_timediv(VALUE self, VALUE n)
fmt = f_add3(rb_usascii_str_new2("T%T"), fmt = f_add3(rb_usascii_str_new2("T%T"),
f, f,
rb_usascii_str_new2("%:z")); 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) if (argc < 1)
n = INT2FIX(0); 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)); 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), if (!gengo(m_real_local_jd(dat),
m_real_year(dat), m_real_year(dat),
argv2)) 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)); dt_lite_iso8601_timediv(self, n));
return f_add(f_add(rb_f_sprintf(2, argv2), 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)); 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", d_lite_mday, 0);
rb_define_method(cDate, "day_fraction", d_lite_day_fraction, 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, "cwyear", d_lite_cwyear, 0);
rb_define_method(cDate, "cweek", d_lite_cweek, 0); rb_define_method(cDate, "cweek", d_lite_cweek, 0);
rb_define_method(cDate, "cwday", d_lite_cwday, 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, "wday", d_lite_wday, 0);
rb_define_method(cDate, "sunday?", d_lite_sunday_p, 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); rb_define_method(cDate, "nth_kday?", d_lite_nth_kday_p, 2);
#endif #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, "julian?", d_lite_julian_p, 0);
rb_define_method(cDate, "gregorian?", d_lite_gregorian_p, 0); rb_define_method(cDate, "gregorian?", d_lite_gregorian_p, 0);
rb_define_method(cDate, "leap?", d_lite_leap_p, 0); rb_define_method(cDate, "leap?", d_lite_leap_p, 0);

View file

@ -97,6 +97,7 @@
#undef strchr /* avoid AIX weirdness */ #undef strchr /* avoid AIX weirdness */
#if 0
#if !defined __STDC__ && !defined _WIN32 #if !defined __STDC__ && !defined _WIN32
#define const /**/ #define const /**/
static int weeknumber(); 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); static int weeknumber_v(const struct tmx *tmx, int firstweekday);
adddecl(static int iso8601wknum_v(const struct tmx *tmx);) adddecl(static int iso8601wknum_v(const struct tmx *tmx);)
#endif #endif
#endif
#ifdef STDC_HEADERS #ifdef STDC_HEADERS
#include <stdlib.h> #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(LOWER)|BIT_OF(CHCASE));
flags |= BIT_OF(UPPER); flags |= BIT_OF(UPPER);
} }
if (tmx->wday < 0 || tmx->wday > 6) if (tmx_wday < 0 || tmx_wday > 6)
i = 1, tp = "?"; i = 1, tp = "?";
else else
i = 3, tp = days_l[tmx->wday]; i = 3, tp = days_l[tmx_wday];
break; break;
case 'A': /* full weekday name */ 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(LOWER)|BIT_OF(CHCASE));
flags |= BIT_OF(UPPER); flags |= BIT_OF(UPPER);
} }
if (tmx->wday < 0 || tmx->wday > 6) if (tmx_wday < 0 || tmx_wday > 6)
i = 1, tp = "?"; i = 1, tp = "?";
else else
i = strlen(tp = days_l[tmx->wday]); i = strlen(tp = days_l[tmx_wday]);
break; break;
#ifdef SYSV_EXT #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(LOWER)|BIT_OF(CHCASE));
flags |= BIT_OF(UPPER); flags |= BIT_OF(UPPER);
} }
if (tmx->mon < 1 || tmx->mon > 12) if (tmx_mon < 1 || tmx_mon > 12)
i = 1, tp = "?"; i = 1, tp = "?";
else else
i = 3, tp = months_l[tmx->mon-1]; i = 3, tp = months_l[tmx_mon-1];
break; break;
case 'B': /* full month name */ 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(LOWER)|BIT_OF(CHCASE));
flags |= BIT_OF(UPPER); flags |= BIT_OF(UPPER);
} }
if (tmx->mon < 1 || tmx->mon > 12) if (tmx_mon < 1 || tmx_mon > 12)
i = 1, tp = "?"; i = 1, tp = "?";
else else
i = strlen(tp = months_l[tmx->mon-1]); i = strlen(tp = months_l[tmx_mon-1]);
break; break;
case 'c': /* appropriate date and time representation */ case 'c': /* appropriate date and time representation */
@ -345,17 +347,17 @@ date_strftime_with_tmx(char *s, size_t maxsize, const char *format,
continue; continue;
case 'd': /* day of the month, 01 - 31 */ 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); FMT('0', 2, "d", (int)i);
continue; continue;
case 'H': /* hour, 24-hour clock, 00 - 23 */ 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); FMT('0', 2, "d", (int)i);
continue; continue;
case 'I': /* hour, 12-hour clock, 01 - 12 */ case 'I': /* hour, 12-hour clock, 01 - 12 */
i = range(0, tmx->hour, 23); i = range(0, tmx_hour, 23);
if (i == 0) if (i == 0)
i = 12; i = 12;
else if (i > 12) else if (i > 12)
@ -364,16 +366,16 @@ date_strftime_with_tmx(char *s, size_t maxsize, const char *format,
continue; continue;
case 'j': /* day of the year, 001 - 366 */ case 'j': /* day of the year, 001 - 366 */
FMT('0', 3, "d", tmx->yday); FMT('0', 3, "d", tmx_yday);
continue; continue;
case 'm': /* month, 01 - 12 */ case 'm': /* month, 01 - 12 */
i = range(1, tmx->mon, 12); i = range(1, tmx_mon, 12);
FMT('0', 2, "d", (int)i); FMT('0', 2, "d", (int)i);
continue; continue;
case 'M': /* minute, 00 - 59 */ case 'M': /* minute, 00 - 59 */
i = range(0, tmx->min, 59); i = range(0, tmx_min, 59);
FMT('0', 2, "d", (int)i); FMT('0', 2, "d", (int)i);
continue; 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(UPPER)|BIT_OF(CHCASE));
flags |= BIT_OF(LOWER); flags |= BIT_OF(LOWER);
} }
i = range(0, tmx->hour, 23); i = range(0, tmx_hour, 23);
if (i < 12) if (i < 12)
tp = ampm[0]; tp = ampm[0];
else else
@ -394,14 +396,14 @@ date_strftime_with_tmx(char *s, size_t maxsize, const char *format,
case 's': case 's':
{ {
VALUE sec = div(tmx->timev, INT2FIX(1)); VALUE sec = div(tmx_timev, INT2FIX(1));
FMTV('0', 1, "d", sec); FMTV('0', 1, "d", sec);
} }
continue; continue;
case 'Q': case 'Q':
{ {
VALUE sec = div(tmx->timev, VALUE sec = div(tmx_timev,
rb_rational_new2(INT2FIX(1), rb_rational_new2(INT2FIX(1),
INT2FIX(1000))); INT2FIX(1000)));
FMTV('0', 1, "d", sec); FMTV('0', 1, "d", sec);
@ -409,21 +411,21 @@ date_strftime_with_tmx(char *s, size_t maxsize, const char *format,
continue; continue;
case 'S': /* second, 00 - 60 */ case 'S': /* second, 00 - 60 */
i = range(0, tmx->sec, 60); i = range(0, tmx_sec, 60);
FMT('0', 2, "d", (int)i); FMT('0', 2, "d", (int)i);
continue; continue;
case 'U': /* week of year, Sunday is first day of week */ 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; continue;
case 'w': /* weekday, Sunday == 0, 0 - 6 */ 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); FMT('0', 1, "d", (int)i);
continue; continue;
case 'W': /* week of year, Monday is first day of week */ 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; continue;
case 'x': /* appropriate date representation */ case 'x': /* appropriate date representation */
@ -435,17 +437,17 @@ date_strftime_with_tmx(char *s, size_t maxsize, const char *format,
continue; continue;
case 'y': /* year without a century, 00 - 99 */ 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); FMT('0', 2, "d", (int)i);
continue; continue;
case 'Y': /* year with century */ case 'Y': /* year with century */
if (FIXNUM_P(tmx->year)) { if (FIXNUM_P(tmx_year)) {
long y = FIX2LONG(tmx->year); long y = FIX2LONG(tmx_year);
FMT('0', 0 <= y ? 4 : 5, "ld", y); FMT('0', 0 <= y ? 4 : 5, "ld", y);
} }
else { else {
FMTV('0', 4, "d", tmx->year); FMTV('0', 4, "d", tmx_year);
} }
continue; continue;
@ -455,7 +457,7 @@ date_strftime_with_tmx(char *s, size_t maxsize, const char *format,
long aoff; long aoff;
int hl, hw; 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; aoff = off;
if (aoff < 0) 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(UPPER)|BIT_OF(CHCASE));
flags |= BIT_OF(LOWER); flags |= BIT_OF(LOWER);
} }
if (tmx->zone == NULL) if (tmx_zone == NULL)
tp = ""; tp = "";
else else
tp = tmx->zone; tp = tmx_zone;
i = strlen(tp); i = strlen(tp);
break; break;
@ -570,7 +572,7 @@ date_strftime_with_tmx(char *s, size_t maxsize, const char *format,
continue; continue;
case 'e': /* day of month, blank padded */ case 'e': /* day of month, blank padded */
FMT(' ', 2, "d", range(1, tmx->mday, 31)); FMT(' ', 2, "d", range(1, tmx_mday, 31));
continue; continue;
case 'r': /* time as %I:%M:%S %p */ 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 #ifdef SUNOS_EXT
case 'k': /* hour, 24-hour clock, blank pad */ 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); FMT(' ', 2, "d", (int)i);
continue; continue;
case 'l': /* hour, 12-hour clock, 1 - 12, blank pad */ 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) if (i == 0)
i = 12; i = 12;
else if (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 #ifdef POSIX2_DATE
case 'C': case 'C':
FMTV('0', 2, "d", div(tmx->year, INT2FIX(100))); FMTV('0', 2, "d", div(tmx_year, INT2FIX(100)));
continue; continue;
case 'E': case 'E':
@ -627,51 +629,36 @@ date_strftime_with_tmx(char *s, size_t maxsize, const char *format,
goto again; goto again;
goto unknown; goto unknown;
case 'V': /* week of year according ISO 8601 */ case 'V': /* week of year according ISO 8601 */
FMT('0', 2, "d", iso8601wknum_v(tmx)); FMT('0', 2, "d", tmx_cweek);
continue; continue;
case 'u': case 'u':
/* ISO 8601: Weekday as a decimal number [1 (Monday) - 7] */ /* 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; continue;
#endif /* POSIX2_DATE */ #endif /* POSIX2_DATE */
#ifdef ISO_DATE_EXT #ifdef ISO_DATE_EXT
case 'G': case 'G':
case 'g': case 'g':
/* {
* Year of ISO week. VALUE yv = tmx_cwyear;
*
* 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));
if (*format == 'G') { if (*format == 'G') {
if (FIXNUM_P(yv)) { if (FIXNUM_P(yv)) {
long y = FIX2LONG(yv); long y = FIX2LONG(yv);
FMT('0', 0 <= y ? 4 : 5, "ld", y); FMT('0', 0 <= y ? 4 : 5, "ld", y);
} }
else { else {
FMTV('0', 4, "d", yv); FMTV('0', 4, "d", yv);
} }
} }
else { else {
yv = mod(yv, INT2FIX(100)); yv = mod(yv, INT2FIX(100));
y = FIX2LONG(yv); y = FIX2LONG(yv);
FMT('0', 2, "ld", y); FMT('0', 2, "ld", y);
} }
continue; continue;
} }
#endif /* ISO_DATE_EXT */ #endif /* ISO_DATE_EXT */
@ -696,7 +683,7 @@ date_strftime_with_tmx(char *s, size_t maxsize, const char *format,
NEEDS(precision); NEEDS(precision);
{ {
VALUE subsec = mod(tmx->timev, INT2FIX(1)); VALUE subsec = mod(tmx_timev, INT2FIX(1));
int ww; int ww;
long n; 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); return date_strftime_with_tmx(s, maxsize, format, tmx);
} }
#if 0
/* isleap --- is a year a leap year? */ /* isleap --- is a year a leap year? */
#ifndef __STDC__ #ifndef __STDC__
@ -837,21 +825,21 @@ tmx2tm_noyear(const struct tmx *tmx, struct tm *result)
struct tm tm; struct tm tm;
/* for isleap() in iso8601wknum. +100 is -1900 (mod 400). */ /* for isleap() in iso8601wknum. +100 is -1900 (mod 400). */
tm.tm_year = FIX2INT(mod(tmx->year, INT2FIX(400))) + 100; tm.tm_year = FIX2INT(mod(tmx_year, INT2FIX(400))) + 100;
tm.tm_mon = tmx->mon-1; tm.tm_mon = tmx_mon-1;
tm.tm_mday = tmx->mday; tm.tm_mday = tmx_mday;
tm.tm_hour = tmx->hour; tm.tm_hour = tmx_hour;
tm.tm_min = tmx->min; tm.tm_min = tmx_min;
tm.tm_sec = tmx->sec; tm.tm_sec = tmx_sec;
tm.tm_wday = tmx->wday; tm.tm_wday = tmx_wday;
tm.tm_yday = tmx->yday-1; tm.tm_yday = tmx_yday-1;
tm.tm_isdst = 0; tm.tm_isdst = 0;
#if defined(HAVE_STRUCT_TM_TM_GMTOFF) #if defined(HAVE_STRUCT_TM_TM_GMTOFF)
tm.tm_gmtoff = NUM2LONG(tmx->offset); tm.tm_gmtoff = NUM2LONG(tmx_offset);
#endif #endif
#if defined(HAVE_TM_ZONE) #if defined(HAVE_TM_ZONE)
tm.tm_zone = (char *)tmx->zone; tm.tm_zone = (char *)tmx_zone;
#endif #endif
*result = tm; *result = tm;
} }
@ -1018,6 +1006,7 @@ weeknumber_v(const struct tmx *tmx, int firstweekday)
tmx2tm_noyear(tmx, &tm); tmx2tm_noyear(tmx, &tm);
return weeknumber(&tm, firstweekday); return weeknumber(&tm, firstweekday);
} }
#endif
#if 0 #if 0
/* ADR --- I'm loathe to mess with ado's code ... */ /* ADR --- I'm loathe to mess with ado's code ... */

View file

@ -1,16 +1,49 @@
struct tmx { #ifndef DATE_TMX_H
VALUE year; #define DATE_TMX_H
int yday;
int mon; struct tmx_funcs {
int mday; VALUE (*year)(void *dat);
int hour; int (*yday)(void *dat);
int min; int (*mon)(void *dat);
int sec; int (*mday)(void *dat);
int wday; VALUE (*cwyear)(void *dat);
VALUE offset; int (*cweek)(void *dat);
const char *zone; int (*cwday)(void *dat);
VALUE timev; 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 {
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: Local variables: