From a0cc5b19b7fa4207496a74d2ef8f39480eac44b5 Mon Sep 17 00:00:00 2001 From: shugo Date: Thu, 21 Aug 2008 14:57:35 +0000 Subject: [PATCH] * strftime.c (rb_strftime): supported %F and %N. reverted config.h to ruby.h for Windows. * test/ruby/test_time.rb (TestTime::test_strftime): added tests for %F and %N. * time.c: documented %F and %N. git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@18755 b2dd03c8-39d4-4d8f-98ff-823fe69b080e --- ChangeLog | 10 +++++++++ strftime.c | 47 +++++++++++++++++++++++++++++++++++++++--- test/ruby/test_time.rb | 12 +++++++++++ time.c | 6 +++++- 4 files changed, 71 insertions(+), 4 deletions(-) diff --git a/ChangeLog b/ChangeLog index 3c82b17ba9..37be5cbb23 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,13 @@ +Thu Aug 21 23:51:51 2008 Shugo Maeda + + * strftime.c (rb_strftime): supported %F and %N. + reverted config.h to ruby.h for Windows. + + * test/ruby/test_time.rb (TestTime::test_strftime): added tests + for %F and %N. + + * time.c: documented %F and %N. + Thu Aug 21 20:23:26 2008 Kazuhiro NISHIYAMA * test/ruby/test_m17n_comb.rb (TestM17NComb#test_str_crypt): add diff --git a/strftime.c b/strftime.c index 811173cd7b..cdc1539648 100644 --- a/strftime.c +++ b/strftime.c @@ -45,7 +45,7 @@ * January 1996 */ -#include "ruby/config.h" +#include "ruby/ruby.h" #ifndef GAWK #include @@ -61,6 +61,7 @@ #include #endif #endif +#include /* defaults: season to taste */ #define SYSV_EXT 1 /* stuff in System V ascftime routine */ @@ -193,6 +194,7 @@ rb_strftime(char *s, size_t maxsize, const char *format, const struct tm *timept #endif /* HAVE_TIMEZONE */ #endif /* HAVE_TM_NAME */ #endif /* HAVE_TM_ZONE */ + int precision = -1; /* various tables, useful in North America */ static const char *days_a[] = { @@ -264,6 +266,7 @@ rb_strftime(char *s, size_t maxsize, const char *format, const struct tm *timept *s++ = *format; continue; } + precision = -1; again: switch (*++format) { case '\0': @@ -587,11 +590,49 @@ rb_strftime(char *s, size_t maxsize, const char *format, const struct tm *timept sprintf(tbuf, "%03ld", ts->tv_nsec / 1000000); break; - case 'N': /* nanosecond, 000000000 - 999999999 */ - sprintf(tbuf, "%09ld", ts->tv_nsec); + case 'N': + /* + * fractional second digits. default is 9 digits + * (nanosecond). + * + * %3N millisecond (3 digits) + * %6N microsecond (6 digits) + * %9N nanosecond (9 digits) + */ + { + char fmt[10]; + long n = ts->tv_nsec; + + if (precision < 0 || precision > 9) { + precision = 9; + } + if (precision == 0) break; + n /= pow(10, 9 - precision); + sprintf(fmt, "%%0%dld", precision); + sprintf(tbuf, fmt, n); + } + break; + + case 'F': /* Equivalent to %Y-%m-%d */ + { + int mon, mday; + mon = range(0, timeptr->tm_mon, 11) + 1; + mday = range(1, timeptr->tm_mday, 31); + sprintf(tbuf, "%ld-%02d-%02d", + 1900L + timeptr->tm_year, mon, mday); + } break; default: + if (isdigit(*format)) { + const char *p = format; + while (isdigit(*p)) p++; + if (*p == 'N') { + precision = atoi(format); + format = p - 1; + goto again; + } + } tbuf[0] = '%'; tbuf[1] = *format; tbuf[2] = '\0'; diff --git a/test/ruby/test_time.rb b/test/ruby/test_time.rb index a84cbd9ec6..6188a3064b 100644 --- a/test/ruby/test_time.rb +++ b/test/ruby/test_time.rb @@ -383,5 +383,17 @@ class TestTime < Test::Unit::TestCase t = Time.at(946684800, 123456.789) assert_equal("123", t.strftime("%L")) assert_equal("123456789", t.strftime("%N")) + assert_equal("123", t.strftime("%3N")) + assert_equal("123456", t.strftime("%6N")) + assert_equal("123456789", t.strftime("%9N")) + assert_equal("123456789", t.strftime("%10N")) + assert_equal("123456789", t.strftime("%1" + "0" * 100 + "N")) + assert_equal("", t.strftime("%0N")) + assert_equal("%3S", t.strftime("%3S")) + fmt = "%1" + "0" * 100 + "S" + assert_equal(fmt, t.strftime(fmt)) + + t = Time.mktime(2001, 10, 1) + assert_equal("2001-10-01", t.strftime("%F")) end end diff --git a/time.c b/time.c index 3556870ada..33977d9254 100644 --- a/time.c +++ b/time.c @@ -2056,13 +2056,17 @@ rb_strftime_alloc(char **buf, const char *format, * %B - The full month name (``January'') * %c - The preferred local date and time representation * %d - Day of the month (01..31) + * %F - Equivalent to %Y-%m-%d (the ISO 8601 date format) * %H - Hour of the day, 24-hour clock (00..23) * %I - Hour of the day, 12-hour clock (01..12) * %j - Day of the year (001..366) * %L - Millisecond of the second (000..999) * %m - Month of the year (01..12) * %M - Minute of the hour (00..59) - * %N - Nanosecond of the second (000000000..999999999) + * %N - Fractional seconds digits, default is 9 digits (nanosecond) + * %3N millisecond (3 digits) + * %6N microsecond (6 digits) + * %9N nanosecond (9 digits) * %p - Meridian indicator (``AM'' or ``PM'') * %S - Second of the minute (00..60) * %U - Week number of the current year,