summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ChangeLog10
-rw-r--r--strftime.c47
-rw-r--r--test/ruby/test_time.rb12
-rw-r--r--time.c6
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 <shugo@ruby-lang.org>
+
+ * strftime.c (rb_strftime): supported %F and %<precision>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 <zn@mbf.nifty.com>
* 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 <stdio.h>
@@ -61,6 +61,7 @@
#include <sys/time.h>
#endif
#endif
+#include <math.h>
/* 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,