diff options
-rw-r--r-- | ChangeLog | 6 | ||||
-rw-r--r-- | ext/date/date_core.c | 68 | ||||
-rw-r--r-- | ext/date/date_strftime.c | 14 | ||||
-rw-r--r-- | ext/date/date_tmx.h | 8 | ||||
-rw-r--r-- | test/date/test_date_strftime.rb | 9 |
5 files changed, 79 insertions, 26 deletions
@@ -1,3 +1,9 @@ +Wed Jun 29 23:42:51 2011 Tadayoshi Funaba <[email protected]> + + * ext/date/date_core.c: avoided using timev. + * ext/date/date_strftime.c: ditto. + * ext/date/date_tmx.h: ditto. + Wed Jun 29 23:17:57 2011 WATANABE Hirofumi <[email protected]> * ext/openssl/ossl.h (OPENSSL_SYS_WIN32): support for mingw(msys). diff --git a/ext/date/date_core.c b/ext/date/date_core.c index d129f232e6..89fa4761c9 100644 --- a/ext/date/date_core.c +++ b/ext/date/date_core.c @@ -172,6 +172,7 @@ f_negative_p(VALUE x) #define MINUTE_IN_SECONDS 60 #define HOUR_IN_SECONDS 3600 #define DAY_IN_SECONDS 86400 +#define SECOND_IN_MILLISECONDS 1000 #define SECOND_IN_NANOSECONDS 1000000000 #define JC_PERIOD0 1461 /* 365.25 * 4 */ @@ -932,6 +933,14 @@ ns_to_day(VALUE n) return f_quo(n, day_in_nanoseconds); } +#ifndef NDEBUG +static VALUE +ms_to_sec(VALUE n) +{ + return f_quo(n, INT2FIX(SECOND_IN_MILLISECONDS)); +} +#endif + static VALUE ns_to_sec(VALUE n) { @@ -976,6 +985,14 @@ day_to_ns(VALUE d) #endif static VALUE +sec_to_ms(VALUE s) +{ + if (safe_mul_p(s, SECOND_IN_MILLISECONDS)) + return LONG2FIX(FIX2LONG(s) * SECOND_IN_MILLISECONDS); + return f_mul(s, INT2FIX(SECOND_IN_MILLISECONDS)); +} + +static VALUE sec_to_ns(VALUE s) { if (safe_mul_p(s, SECOND_IN_NANOSECONDS)) @@ -6596,6 +6613,38 @@ date_strftime_alloc(char **buf, const char *format, } static VALUE +tmx_m_secs(union DateData *x) +{ + VALUE s; + int df; + + s = day_to_sec(f_sub(m_real_jd(x), + UNIX_EPOCH_IN_CJD)); + if (simple_dat_p(x)) + return s; + df = m_df(x); + if (df) + s = f_add(s, INT2FIX(df)); + return s; +} + +#define MILLISECOND_IN_NANOSECONDS 1000000 + +static VALUE +tmx_m_msecs(union DateData *x) +{ + VALUE s, sf; + + s = sec_to_ms(tmx_m_secs(x)); + if (simple_dat_p(x)) + return s; + sf = m_sf(x); + if (f_nonzero_p(sf)) + s = f_add(s, f_div(sf, INT2FIX(MILLISECOND_IN_NANOSECONDS))); + return s; +} + +static VALUE tmx_m_of(union DateData *x) { return INT2FIX(m_of(x)); @@ -6607,17 +6656,6 @@ 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, @@ -6632,9 +6670,11 @@ static struct tmx_funcs tmx_funcs = { (int (*)(void *))m_hour, (int (*)(void *))m_min, (int (*)(void *))m_sec, + (VALUE (*)(void *))m_sf_in_sec, + (VALUE (*)(void *))tmx_m_secs, + (VALUE (*)(void *))tmx_m_msecs, (VALUE (*)(void *))tmx_m_of, - (char *(*)(void *))tmx_m_zone, - (VALUE (*)(void *))tmx_m_timev + (char *(*)(void *))tmx_m_zone }; static void @@ -8870,6 +8910,8 @@ date_s_test_unit_conv(VALUE klass) { if (!test_unit_v2v_iter(sec_to_day, day_to_sec)) return Qfalse; + if (!test_unit_v2v_iter(ms_to_sec, sec_to_ms)) + return Qfalse; if (!test_unit_v2v_iter(ns_to_day, day_to_ns)) return Qfalse; if (!test_unit_v2v_iter(ns_to_sec, sec_to_ns)) diff --git a/ext/date/date_strftime.c b/ext/date/date_strftime.c index 5781d3b795..02ad9a47ae 100644 --- a/ext/date/date_strftime.c +++ b/ext/date/date_strftime.c @@ -406,19 +406,11 @@ date_strftime_with_tmx(char *s, size_t maxsize, const char *format, break; case 's': - { - VALUE sec = div(tmx_timev, INT2FIX(1)); - FMTV('0', 1, "d", sec); - } + FMTV('0', 1, "d", tmx_secs); continue; case 'Q': - { - VALUE sec = div(tmx_timev, - rb_rational_new2(INT2FIX(1), - INT2FIX(1000))); - FMTV('0', 1, "d", sec); - } + FMTV('0', 1, "d", tmx_msecs); continue; case 'S': /* second, 00 - 59 */ @@ -697,7 +689,7 @@ date_strftime_with_tmx(char *s, size_t maxsize, const char *format, NEEDS(precision); { - VALUE subsec = mod(tmx_timev, INT2FIX(1)); + VALUE subsec = tmx_sec_fraction; int ww; long n; diff --git a/ext/date/date_tmx.h b/ext/date/date_tmx.h index 2bdb80c316..0e56c9b4f0 100644 --- a/ext/date/date_tmx.h +++ b/ext/date/date_tmx.h @@ -15,9 +15,11 @@ struct tmx_funcs { int (*hour)(void *dat); int (*min)(void *dat); int (*sec)(void *dat); + VALUE (*sec_fraction)(void *dat); + VALUE (*secs)(void *dat); + VALUE (*msecs)(void *dat); VALUE (*offset)(void *dat); char *(*zone)(void *dat); - VALUE (*timev)(void *dat); }; struct tmx { void *dat; @@ -39,9 +41,11 @@ struct tmx { #define tmx_hour tmx_attr(hour) #define tmx_min tmx_attr(min) #define tmx_sec tmx_attr(sec) +#define tmx_sec_fraction tmx_attr(sec_fraction) +#define tmx_secs tmx_attr(secs) +#define tmx_msecs tmx_attr(msecs) #define tmx_offset tmx_attr(offset) #define tmx_zone tmx_attr(zone) -#define tmx_timev tmx_attr(timev) #endif diff --git a/test/date/test_date_strftime.rb b/test/date/test_date_strftime.rb index 61a82a17f5..8b96f16049 100644 --- a/test/date/test_date_strftime.rb +++ b/test/date/test_date_strftime.rb @@ -194,6 +194,15 @@ class TestDateStrftime < Test::Unit::TestCase end end + def test_strftime_milli + s = '1970-01-01T00:00:00.123456789' + d = DateTime.parse(s) + assert_equal('123', d.strftime('%Q')) + s = '1970-01-02T02:03:04.123456789' + d = DateTime.parse(s) + assert_equal('93784123', d.strftime('%Q')) + end + def test_strftime__minus d = DateTime.new(1969, 12, 31, 23, 59, 59) assert_equal('-1', d.strftime('%s')) |