mirror of
https://github.com/ruby/ruby.git
synced 2022-11-09 12:17:21 -05:00
* ext/date/date_core.c: replacement of implementation of
strftime. It has some limitations that is same as Time's one. [experimental] * ext/date/date_strftime.c: new. * ext/date/lib/date/format.c: removed ruby version of strftime. git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@31135 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
This commit is contained in:
parent
7bc47c0260
commit
434157444f
6 changed files with 1509 additions and 210 deletions
|
@ -1,3 +1,11 @@
|
||||||
|
Sun Mar 20 21:34:49 2011 Tadayoshi Funaba <tadf@dotrb.org>
|
||||||
|
|
||||||
|
* ext/date/date_core.c: replacement of implementation of
|
||||||
|
strftime. It has some limitations that is same as Time's
|
||||||
|
one. [experimental]
|
||||||
|
* ext/date/date_strftime.c: new.
|
||||||
|
* ext/date/lib/date/format.c: removed ruby version of strftime.
|
||||||
|
|
||||||
Sun Mar 20 12:43:12 2011 Tanaka Akira <akr@fsij.org>
|
Sun Mar 20 12:43:12 2011 Tanaka Akira <akr@fsij.org>
|
||||||
|
|
||||||
* ext/openssl/ossl_x509store.c: parenthesize macro arguments.
|
* ext/openssl/ossl_x509store.c: parenthesize macro arguments.
|
||||||
|
|
|
@ -1464,6 +1464,17 @@ d_lite_year(VALUE self)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static const int yeartab[2][13] = {
|
||||||
|
{ 0, 0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334 },
|
||||||
|
{ 0, 0, 31, 60, 91, 121, 152, 182, 213, 244, 274, 305, 335 }
|
||||||
|
};
|
||||||
|
|
||||||
|
static int
|
||||||
|
civil_to_yday(int y, int m, int d)
|
||||||
|
{
|
||||||
|
return yeartab[leap_p(y) ? 1 : 0][m] + d;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* call-seq:
|
* call-seq:
|
||||||
* d.yday
|
* d.yday
|
||||||
|
@ -1481,9 +1492,8 @@ d_lite_yday(VALUE self)
|
||||||
if (!light_mode_p(dat))
|
if (!light_mode_p(dat))
|
||||||
return iforward0("yday_r");
|
return iforward0("yday_r");
|
||||||
{
|
{
|
||||||
get_d_jd(dat);
|
get_d_civil(dat);
|
||||||
jd_to_ordinal(dat->l.jd, dat->l.sg, &ry, &rd);
|
return INT2FIX(civil_to_yday(dat->l.year, dat->l.mon, dat->l.mday));
|
||||||
return INT2FIX(rd);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2322,6 +2332,158 @@ d_lite_inspect(VALUE self)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#include <errno.h>
|
||||||
|
#include "timev.h"
|
||||||
|
|
||||||
|
size_t
|
||||||
|
date_strftime(char *s, size_t maxsize, const char *format,
|
||||||
|
const struct vtm *vtm, VALUE timev, int gmt);
|
||||||
|
|
||||||
|
#define SMALLBUF 100
|
||||||
|
static size_t
|
||||||
|
date_strftime_alloc(char **buf, const char *format,
|
||||||
|
struct vtm *vtm, VALUE timev)
|
||||||
|
{
|
||||||
|
size_t size, len, flen;
|
||||||
|
|
||||||
|
(*buf)[0] = '\0';
|
||||||
|
flen = strlen(format);
|
||||||
|
if (flen == 0) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
errno = 0;
|
||||||
|
len = date_strftime(*buf, SMALLBUF, format, vtm, timev, 0);
|
||||||
|
if (len != 0 || (**buf == '\0' && errno != ERANGE)) return len;
|
||||||
|
for (size=1024; ; size*=2) {
|
||||||
|
*buf = xmalloc(size);
|
||||||
|
(*buf)[0] = '\0';
|
||||||
|
len = date_strftime(*buf, size, format, vtm, timev, 0);
|
||||||
|
/*
|
||||||
|
* buflen can be zero EITHER because there's not enough
|
||||||
|
* room in the string, or because the control command
|
||||||
|
* goes to the empty string. Make a reasonable guess that
|
||||||
|
* if the buffer is 1024 times bigger than the length of the
|
||||||
|
* format string, it's not failing for lack of room.
|
||||||
|
*/
|
||||||
|
if (len > 0 || size >= 1024 * flen) break;
|
||||||
|
xfree(*buf);
|
||||||
|
}
|
||||||
|
return len;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
d_lite_set_vtm_and_timev(VALUE self, struct vtm *vtm, VALUE *timev)
|
||||||
|
{
|
||||||
|
get_d1(self);
|
||||||
|
|
||||||
|
if (!light_mode_p(dat)) {
|
||||||
|
vtm->year = iforward0("year_r");
|
||||||
|
vtm->mon = FIX2INT(iforward0("mon_r"));
|
||||||
|
vtm->mday = FIX2INT(iforward0("mday_r"));
|
||||||
|
vtm->hour = FIX2INT(iforward0("hour_r"));
|
||||||
|
vtm->min = FIX2INT(iforward0("min_r"));
|
||||||
|
vtm->sec = FIX2INT(iforward0("sec_r"));
|
||||||
|
vtm->subsecx = iforward0("sec_fraction_r");
|
||||||
|
vtm->utc_offset = INT2FIX(0);
|
||||||
|
vtm->wday = FIX2INT(iforward0("wday_r"));
|
||||||
|
vtm->yday = FIX2INT(iforward0("yday_r"));
|
||||||
|
vtm->isdst = 0;
|
||||||
|
vtm->zone = RSTRING_PTR(iforward0("zone_r"));
|
||||||
|
*timev = f_mul(f_sub(dat->r.ajd,
|
||||||
|
rb_rational_new2(INT2FIX(4881175), INT2FIX(2))),
|
||||||
|
INT2FIX(86400));
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
get_d_jd(dat);
|
||||||
|
get_d_civil(dat);
|
||||||
|
|
||||||
|
vtm->year = LONG2NUM(dat->l.year);
|
||||||
|
vtm->mon = dat->l.mon;
|
||||||
|
vtm->mday = dat->l.mday;
|
||||||
|
vtm->hour = 0;
|
||||||
|
vtm->min = 0;
|
||||||
|
vtm->sec = 0;
|
||||||
|
vtm->subsecx = INT2FIX(0);
|
||||||
|
vtm->utc_offset = INT2FIX(0);
|
||||||
|
vtm->wday = jd_to_wday(dat->l.jd);
|
||||||
|
vtm->yday = civil_to_yday(dat->l.year, dat->l.mon, dat->l.mday);
|
||||||
|
vtm->isdst = 0;
|
||||||
|
vtm->zone = "+00:00";
|
||||||
|
*timev = f_mul(INT2FIX(dat->l.jd - 2440588),
|
||||||
|
INT2FIX(86400));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static VALUE
|
||||||
|
date_strftime_internal(int argc, VALUE *argv, VALUE self,
|
||||||
|
const char *default_fmt,
|
||||||
|
void (*func)(VALUE, struct vtm *, VALUE *))
|
||||||
|
{
|
||||||
|
get_d1(self);
|
||||||
|
{
|
||||||
|
VALUE vfmt;
|
||||||
|
const char *fmt;
|
||||||
|
long len;
|
||||||
|
char buffer[SMALLBUF], *buf = buffer;
|
||||||
|
struct vtm vtm;
|
||||||
|
VALUE timev;
|
||||||
|
VALUE str;
|
||||||
|
|
||||||
|
rb_scan_args(argc, argv, "01", &vfmt);
|
||||||
|
|
||||||
|
if (argc < 1)
|
||||||
|
vfmt = rb_usascii_str_new2(default_fmt);
|
||||||
|
else {
|
||||||
|
StringValue(vfmt);
|
||||||
|
if (!rb_enc_str_asciicompat_p(vfmt)) {
|
||||||
|
rb_raise(rb_eArgError,
|
||||||
|
"format should have ASCII compatible encoding");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
fmt = RSTRING_PTR(vfmt);
|
||||||
|
len = RSTRING_LEN(vfmt);
|
||||||
|
(*func)(self, &vtm, &timev);
|
||||||
|
if (memchr(fmt, '\0', len)) {
|
||||||
|
/* Ruby string may contain \0's. */
|
||||||
|
const char *p = fmt, *pe = fmt + len;
|
||||||
|
|
||||||
|
str = rb_str_new(0, 0);
|
||||||
|
while (p < pe) {
|
||||||
|
len = date_strftime_alloc(&buf, p, &vtm, timev);
|
||||||
|
rb_str_cat(str, buf, len);
|
||||||
|
p += strlen(p);
|
||||||
|
if (buf != buffer) {
|
||||||
|
xfree(buf);
|
||||||
|
buf = buffer;
|
||||||
|
}
|
||||||
|
for (fmt = p; p < pe && !*p; ++p);
|
||||||
|
if (p > fmt) rb_str_cat(str, fmt, p - fmt);
|
||||||
|
}
|
||||||
|
return str;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
len = date_strftime_alloc(&buf, fmt, &vtm, timev);
|
||||||
|
|
||||||
|
str = rb_str_new(buf, len);
|
||||||
|
if (buf != buffer) xfree(buf);
|
||||||
|
rb_enc_copy(str, vfmt);
|
||||||
|
return str;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* call-seq:
|
||||||
|
* d.strftime([format="%F"])
|
||||||
|
*
|
||||||
|
* Return a formatted string.
|
||||||
|
*/
|
||||||
|
static VALUE
|
||||||
|
d_lite_strftime(int argc, VALUE *argv, VALUE self)
|
||||||
|
{
|
||||||
|
return date_strftime_internal(argc, argv, self,
|
||||||
|
"%F", d_lite_set_vtm_and_timev);
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* call-seq:
|
* call-seq:
|
||||||
* d.marshal_dump
|
* d.marshal_dump
|
||||||
|
@ -3074,10 +3236,8 @@ dt_lite_yday(VALUE self)
|
||||||
if (!light_mode_p(dat))
|
if (!light_mode_p(dat))
|
||||||
return iforward0("yday_r");
|
return iforward0("yday_r");
|
||||||
{
|
{
|
||||||
get_dt_jd(dat);
|
get_dt_civil(dat);
|
||||||
get_dt_df(dat);
|
return INT2FIX(civil_to_yday(dat->l.year, dat->l.mon, dat->l.mday));
|
||||||
jd_to_ordinal(local_jd(dat), dat->l.sg, &ry, &rd);
|
|
||||||
return INT2FIX(rd);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3806,6 +3966,64 @@ dt_lite_inspect(VALUE self)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
dt_lite_set_vtm_and_timev(VALUE self, struct vtm *vtm, VALUE *timev)
|
||||||
|
{
|
||||||
|
get_dt1(self);
|
||||||
|
|
||||||
|
if (!light_mode_p(dat)) {
|
||||||
|
vtm->year = iforward0("year_r");
|
||||||
|
vtm->mon = FIX2INT(iforward0("mon_r"));
|
||||||
|
vtm->mday = FIX2INT(iforward0("mday_r"));
|
||||||
|
vtm->hour = FIX2INT(iforward0("hour_r"));
|
||||||
|
vtm->min = FIX2INT(iforward0("min_r"));
|
||||||
|
vtm->sec = FIX2INT(iforward0("sec_r"));
|
||||||
|
vtm->subsecx = iforward0("sec_fraction_r");
|
||||||
|
vtm->utc_offset = INT2FIX(0);
|
||||||
|
vtm->wday = FIX2INT(iforward0("wday_r"));
|
||||||
|
vtm->yday = FIX2INT(iforward0("yday_r"));
|
||||||
|
vtm->isdst = 0;
|
||||||
|
vtm->zone = RSTRING_PTR(iforward0("zone_r"));
|
||||||
|
*timev = f_mul(f_sub(dat->r.ajd,
|
||||||
|
rb_rational_new2(INT2FIX(4881175), INT2FIX(2))),
|
||||||
|
INT2FIX(86400));
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
get_dt_jd(dat);
|
||||||
|
get_dt_civil(dat);
|
||||||
|
get_dt_time(dat);
|
||||||
|
|
||||||
|
vtm->year = LONG2NUM(dat->l.year);
|
||||||
|
vtm->mon = dat->l.mon;
|
||||||
|
vtm->mday = dat->l.mday;
|
||||||
|
vtm->hour = dat->l.hour;
|
||||||
|
vtm->min = dat->l.min;
|
||||||
|
vtm->sec = dat->l.sec;
|
||||||
|
vtm->subsecx = LONG2NUM(dat->l.sf);
|
||||||
|
vtm->utc_offset = INT2FIX(dat->l.of);
|
||||||
|
vtm->wday = jd_to_wday(local_jd(dat));
|
||||||
|
vtm->yday = civil_to_yday(dat->l.year, dat->l.mon, dat->l.mday);
|
||||||
|
vtm->isdst = 0;
|
||||||
|
vtm->zone = RSTRING_PTR(dt_lite_zone(self));
|
||||||
|
*timev = f_mul(f_sub(dt_lite_ajd(self),
|
||||||
|
rb_rational_new2(INT2FIX(4881175), INT2FIX(2))),
|
||||||
|
INT2FIX(86400));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* call-seq:
|
||||||
|
* dt.strftime([format="%FT%T%:z"])
|
||||||
|
*
|
||||||
|
* Return a formatted string.
|
||||||
|
*/
|
||||||
|
static VALUE
|
||||||
|
dt_lite_strftime(int argc, VALUE *argv, VALUE self)
|
||||||
|
{
|
||||||
|
return date_strftime_internal(argc, argv, self,
|
||||||
|
"%FT%T%:z", dt_lite_set_vtm_and_timev);
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* call-seq:
|
* call-seq:
|
||||||
* dt.marshal_dump
|
* dt.marshal_dump
|
||||||
|
@ -4214,6 +4432,7 @@ Init_date_core(void)
|
||||||
|
|
||||||
rb_define_method(cDate, "to_s", d_lite_to_s, 0);
|
rb_define_method(cDate, "to_s", d_lite_to_s, 0);
|
||||||
rb_define_method(cDate, "inspect", d_lite_inspect, 0);
|
rb_define_method(cDate, "inspect", d_lite_inspect, 0);
|
||||||
|
rb_define_method(cDate, "strftime", d_lite_strftime, -1);
|
||||||
|
|
||||||
rb_define_method(cDate, "marshal_dump", d_lite_marshal_dump, 0);
|
rb_define_method(cDate, "marshal_dump", d_lite_marshal_dump, 0);
|
||||||
rb_define_method(cDate, "marshal_load", d_lite_marshal_load, 1);
|
rb_define_method(cDate, "marshal_load", d_lite_marshal_load, 1);
|
||||||
|
@ -4288,6 +4507,7 @@ Init_date_core(void)
|
||||||
|
|
||||||
rb_define_method(cDateTime, "to_s", dt_lite_to_s, 0);
|
rb_define_method(cDateTime, "to_s", dt_lite_to_s, 0);
|
||||||
rb_define_method(cDateTime, "inspect", dt_lite_inspect, 0);
|
rb_define_method(cDateTime, "inspect", dt_lite_inspect, 0);
|
||||||
|
rb_define_method(cDateTime, "strftime", dt_lite_strftime, -1);
|
||||||
|
|
||||||
rb_define_method(cDateTime, "marshal_dump", dt_lite_marshal_dump, 0);
|
rb_define_method(cDateTime, "marshal_dump", dt_lite_marshal_dump, 0);
|
||||||
rb_define_method(cDateTime, "marshal_load", dt_lite_marshal_load, 1);
|
rb_define_method(cDateTime, "marshal_load", dt_lite_marshal_load, 1);
|
||||||
|
|
1252
ext/date/date_strftime.c
Normal file
1252
ext/date/date_strftime.c
Normal file
File diff suppressed because it is too large
Load diff
|
@ -131,208 +131,6 @@ class Date
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
def emit(e, f) # :nodoc:
|
|
||||||
case e
|
|
||||||
when Numeric
|
|
||||||
sign = %w(+ + -)[e <=> 0]
|
|
||||||
e = e.abs
|
|
||||||
end
|
|
||||||
|
|
||||||
s = e.to_s
|
|
||||||
|
|
||||||
if f[:s] && f[:p] == '0'
|
|
||||||
f[:w] -= 1
|
|
||||||
end
|
|
||||||
|
|
||||||
if f[:s] && f[:p] == "\s"
|
|
||||||
s[0,0] = sign
|
|
||||||
end
|
|
||||||
|
|
||||||
if f[:p] != '-'
|
|
||||||
s = s.rjust(f[:w], f[:p])
|
|
||||||
end
|
|
||||||
|
|
||||||
if f[:s] && f[:p] != "\s"
|
|
||||||
s[0,0] = sign
|
|
||||||
end
|
|
||||||
|
|
||||||
s = s.upcase if f[:u]
|
|
||||||
s = s.downcase if f[:d]
|
|
||||||
s
|
|
||||||
end
|
|
||||||
|
|
||||||
def emit_w(e, w, f) # :nodoc:
|
|
||||||
f[:w] = [f[:w], w].compact.max
|
|
||||||
emit(e, f)
|
|
||||||
end
|
|
||||||
|
|
||||||
def emit_n(e, w, f) # :nodoc:
|
|
||||||
f[:p] ||= '0'
|
|
||||||
emit_w(e, w, f)
|
|
||||||
end
|
|
||||||
|
|
||||||
def emit_sn(e, w, f) # :nodoc:
|
|
||||||
if e < 0
|
|
||||||
w += 1
|
|
||||||
f[:s] = true
|
|
||||||
end
|
|
||||||
emit_n(e, w, f)
|
|
||||||
end
|
|
||||||
|
|
||||||
def emit_z(e, w, f) # :nodoc:
|
|
||||||
w += 1
|
|
||||||
f[:s] = true
|
|
||||||
emit_n(e, w, f)
|
|
||||||
end
|
|
||||||
|
|
||||||
def emit_a(e, w, f) # :nodoc:
|
|
||||||
f[:p] ||= "\s"
|
|
||||||
emit_w(e, w, f)
|
|
||||||
end
|
|
||||||
|
|
||||||
def emit_ad(e, w, f) # :nodoc:
|
|
||||||
if f[:x]
|
|
||||||
f[:u] = true
|
|
||||||
f[:d] = false
|
|
||||||
end
|
|
||||||
emit_a(e, w, f)
|
|
||||||
end
|
|
||||||
|
|
||||||
def emit_au(e, w, f) # :nodoc:
|
|
||||||
if f[:x]
|
|
||||||
f[:u] = false
|
|
||||||
f[:d] = true
|
|
||||||
end
|
|
||||||
emit_a(e, w, f)
|
|
||||||
end
|
|
||||||
|
|
||||||
private :emit, :emit_w, :emit_n, :emit_sn, :emit_z,
|
|
||||||
:emit_a, :emit_ad, :emit_au
|
|
||||||
|
|
||||||
def strftime(fmt='%F')
|
|
||||||
fmt.gsub(/%([-_0^#]+)?(\d+)?([EO]?(?::{1,3}z|.))/m) do
|
|
||||||
f = {}
|
|
||||||
m = $&
|
|
||||||
s, w, c = $1, $2, $3
|
|
||||||
if s
|
|
||||||
s.scan(/./) do |k|
|
|
||||||
case k
|
|
||||||
when '-'; f[:p] = '-'
|
|
||||||
when '_'; f[:p] = "\s"
|
|
||||||
when '0'; f[:p] = '0'
|
|
||||||
when '^'; f[:u] = true
|
|
||||||
when '#'; f[:x] = true
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
if w
|
|
||||||
f[:w] = w.to_i
|
|
||||||
end
|
|
||||||
case c
|
|
||||||
when 'A'; emit_ad(DAYNAMES[wday], 0, f)
|
|
||||||
when 'a'; emit_ad(ABBR_DAYNAMES[wday], 0, f)
|
|
||||||
when 'B'; emit_ad(MONTHNAMES[mon], 0, f)
|
|
||||||
when 'b'; emit_ad(ABBR_MONTHNAMES[mon], 0, f)
|
|
||||||
when 'C', 'EC'; emit_sn((year / 100).floor, 2, f)
|
|
||||||
when 'c', 'Ec'; emit_a(strftime('%a %b %e %H:%M:%S %Y'), 0, f)
|
|
||||||
when 'D'; emit_a(strftime('%m/%d/%y'), 0, f)
|
|
||||||
when 'd', 'Od'; emit_n(mday, 2, f)
|
|
||||||
when 'e', 'Oe'; emit_a(mday, 2, f)
|
|
||||||
when 'F'
|
|
||||||
if m == '%F'
|
|
||||||
format('%.4d-%02d-%02d', year, mon, mday) # 4p
|
|
||||||
else
|
|
||||||
emit_a(strftime('%Y-%m-%d'), 0, f)
|
|
||||||
end
|
|
||||||
when 'G'; emit_sn(cwyear, 4, f)
|
|
||||||
when 'g'; emit_n(cwyear % 100, 2, f)
|
|
||||||
when 'H', 'OH'; emit_n(hour, 2, f)
|
|
||||||
when 'h'; emit_ad(strftime('%b'), 0, f)
|
|
||||||
when 'I', 'OI'; emit_n((hour % 12).nonzero? || 12, 2, f)
|
|
||||||
when 'j'; emit_n(yday, 3, f)
|
|
||||||
when 'k'; emit_a(hour, 2, f)
|
|
||||||
when 'L'
|
|
||||||
f[:p] = nil
|
|
||||||
w = f[:w] || 3
|
|
||||||
u = 10**w
|
|
||||||
emit_n((sec_fraction * u).floor, w, f)
|
|
||||||
when 'l'; emit_a((hour % 12).nonzero? || 12, 2, f)
|
|
||||||
when 'M', 'OM'; emit_n(min, 2, f)
|
|
||||||
when 'm', 'Om'; emit_n(mon, 2, f)
|
|
||||||
when 'N'
|
|
||||||
f[:p] = nil
|
|
||||||
w = f[:w] || 9
|
|
||||||
u = 10**w
|
|
||||||
emit_n((sec_fraction * u).floor, w, f)
|
|
||||||
when 'n'; emit_a("\n", 0, f)
|
|
||||||
when 'P'; emit_ad(strftime('%p').downcase, 0, f)
|
|
||||||
when 'p'; emit_au(if hour < 12 then 'AM' else 'PM' end, 0, f)
|
|
||||||
when 'Q'
|
|
||||||
s = ((ajd - UNIX_EPOCH_IN_AJD) / MILLISECONDS_IN_DAY).round
|
|
||||||
emit_sn(s, 1, f)
|
|
||||||
when 'R'; emit_a(strftime('%H:%M'), 0, f)
|
|
||||||
when 'r'; emit_a(strftime('%I:%M:%S %p'), 0, f)
|
|
||||||
when 'S', 'OS'; emit_n(sec, 2, f)
|
|
||||||
when 's'
|
|
||||||
s = ((ajd - UNIX_EPOCH_IN_AJD) / SECONDS_IN_DAY).round
|
|
||||||
emit_sn(s, 1, f)
|
|
||||||
when 'T'
|
|
||||||
if m == '%T'
|
|
||||||
format('%02d:%02d:%02d', hour, min, sec) # 4p
|
|
||||||
else
|
|
||||||
emit_a(strftime('%H:%M:%S'), 0, f)
|
|
||||||
end
|
|
||||||
when 't'; emit_a("\t", 0, f)
|
|
||||||
when 'U', 'W', 'OU', 'OW'
|
|
||||||
emit_n(if c[-1,1] == 'U' then wnum0 else wnum1 end, 2, f)
|
|
||||||
when 'u', 'Ou'; emit_n(cwday, 1, f)
|
|
||||||
when 'V', 'OV'; emit_n(cweek, 2, f)
|
|
||||||
when 'v'; emit_a(strftime('%e-%b-%Y'), 0, f)
|
|
||||||
when 'w', 'Ow'; emit_n(wday, 1, f)
|
|
||||||
when 'X', 'EX'; emit_a(strftime('%H:%M:%S'), 0, f)
|
|
||||||
when 'x', 'Ex'; emit_a(strftime('%m/%d/%y'), 0, f)
|
|
||||||
when 'Y', 'EY'; emit_sn(year, 4, f)
|
|
||||||
when 'y', 'Ey', 'Oy'; emit_n(year % 100, 2, f)
|
|
||||||
when 'Z'; emit_au(strftime('%:z'), 0, f)
|
|
||||||
when /\A(:{0,3})z/
|
|
||||||
t = $1.size
|
|
||||||
sign = if offset < 0 then -1 else +1 end
|
|
||||||
fr = offset.abs
|
|
||||||
ss = fr.div(SECONDS_IN_DAY) # 4p
|
|
||||||
hh, ss = ss.divmod(3600)
|
|
||||||
mm, ss = ss.divmod(60)
|
|
||||||
if t == 3
|
|
||||||
if ss.nonzero? then t = 2
|
|
||||||
elsif mm.nonzero? then t = 1
|
|
||||||
else t = -1
|
|
||||||
end
|
|
||||||
end
|
|
||||||
case t
|
|
||||||
when -1
|
|
||||||
tail = []
|
|
||||||
sep = ''
|
|
||||||
when 0
|
|
||||||
f[:w] -= 2 if f[:w]
|
|
||||||
tail = ['%02d' % mm]
|
|
||||||
sep = ''
|
|
||||||
when 1
|
|
||||||
f[:w] -= 3 if f[:w]
|
|
||||||
tail = ['%02d' % mm]
|
|
||||||
sep = ':'
|
|
||||||
when 2
|
|
||||||
f[:w] -= 6 if f[:w]
|
|
||||||
tail = ['%02d' % mm, '%02d' % ss]
|
|
||||||
sep = ':'
|
|
||||||
end
|
|
||||||
([emit_z(sign * hh, 2, f)] + tail).join(sep)
|
|
||||||
when '%'; emit_a('%', 0, f)
|
|
||||||
when '+'; emit_a(strftime('%a %b %e %H:%M:%S %Z %Y'), 0, f)
|
|
||||||
else
|
|
||||||
m
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
# alias_method :format, :strftime
|
# alias_method :format, :strftime
|
||||||
|
|
||||||
def asctime() strftime('%c') end
|
def asctime() strftime('%c') end
|
||||||
|
|
21
ext/date/timev.h
Normal file
21
ext/date/timev.h
Normal file
|
@ -0,0 +1,21 @@
|
||||||
|
#ifndef RUBY_TIMEV_H
|
||||||
|
#define RUBY_TIMEV_H
|
||||||
|
|
||||||
|
struct vtm {
|
||||||
|
VALUE year; /* 2000 for example. Integer. */
|
||||||
|
int mon; /* 1..12 */
|
||||||
|
int mday; /* 1..31 */
|
||||||
|
int hour; /* 0..23 */
|
||||||
|
int min; /* 0..59 */
|
||||||
|
int sec; /* 0..60 */
|
||||||
|
VALUE subsecx; /* 0 <= subsecx < TIME_SCALE. possibly Rational. */
|
||||||
|
VALUE utc_offset; /* -3600 as -01:00 for example. possibly Rational. */
|
||||||
|
int wday; /* 0:Sunday, 1:Monday, ..., 6:Saturday */
|
||||||
|
int yday; /* 1..366 */
|
||||||
|
int isdst; /* 0:StandardTime 1:DayLightSavingTime */
|
||||||
|
const char *zone; /* "JST", "EST", "EDT", etc. */
|
||||||
|
};
|
||||||
|
|
||||||
|
#define TIME_SCALE 1000000000
|
||||||
|
|
||||||
|
#endif
|
|
@ -47,7 +47,7 @@ class TestDateStrftime < Test::Unit::TestCase
|
||||||
'%t'=>["\t",{}],
|
'%t'=>["\t",{}],
|
||||||
'%u'=>['6',{:cwday=>6}],
|
'%u'=>['6',{:cwday=>6}],
|
||||||
'%V'=>['05',{:cweek=>5}],
|
'%V'=>['05',{:cweek=>5}],
|
||||||
'%v'=>[' 3-Feb-2001',{:mday=>3,:mon=>2,:year=>2001}],
|
'%v'=>[' 3-FEB-2001',{:mday=>3,:mon=>2,:year=>2001}],
|
||||||
'%z'=>['+0000',{:zone=>'+0000',:offset=>0}],
|
'%z'=>['+0000',{:zone=>'+0000',:offset=>0}],
|
||||||
'%+'=>['Sat Feb 3 00:00:00 +00:00 2001',
|
'%+'=>['Sat Feb 3 00:00:00 +00:00 2001',
|
||||||
{:wday=>6,:mon=>2,:mday=>3,
|
{:wday=>6,:mon=>2,:mday=>3,
|
||||||
|
|
Loading…
Reference in a new issue