Project

General

Profile

Feature #3547

%:z and %::z for strftime

Added by akr (Akira Tanaka) over 9 years ago. Updated over 8 years ago.

Status:
Closed
Priority:
Normal
Assignee:
-
Target version:
-
[ruby-dev:41841]

Description

=begin
strftime で %:z と %::z という指定を可能にするのはどうでしょうか。

% ./ruby -e 'p Time.now.strftime("%z %:z %::z")'
"+0900 +09:00 +09:00:00"

時差をフォーマットするのに現在は %z がありますが、これは +hhmm という形です。
これは RFC 822 形式の時刻を表現するにはちょうどいいのですが、
XML Schema や RFC 3339 や W3CDTF で使う、コロンが入った +hh:mm という
形式とは合いません。

そして、最近知ったのですが、GNU coreutils の date には %:z という指定で
+hh:mm という形式を生成する機能があります。
また、コロンをふたつにして %::z とすると +hh:mm:ss と秒まで生成します。

というわけで、Ruby でも %:z と %::z をサポートするのはどうでしょう。

なお、コロンが入った形式はその文字列自体を見て時刻の類であることがわかるので
間違いが起きにくく、この型式はそれ自体良いものだと思います。

% svn diff --diff-cmd diff -x '-u -p'
Index: time.c
===================================================================
--- time.c (revision 28563)
+++ time.c (working copy)
@@ -4346,7 +4346,9 @@ strftimev(const char *fmt, VALUE time)

  • %X - Preferred representation for the time alone, no date
  • %y - Year without a century (00..99)
  • %Y - Year with century
    • * %z - Time zone as hour offset from UTC (e.g. +0900)
    • * %z - Time zone as hour and minute offset from UTC (e.g. +0900)
    • * %:z - hour and minute offset from UTC with a colon (e.g. +09:00)
    • * %::z - hour, minute and second offset from UTC (e.g. +09:00:00)
  • %Z - Time zone name
  • %% - Literal ``%'' character * Index: strftime.c =================================================================== --- strftime.c (revision 28563) +++ strftime.c (working copy) @@ -215,7 +215,7 @@ rb_strftime_with_timespec(char s, size_ #endif #endif / HAVE_TM_NAME / #endif / HAVE_TM_ZONE */
    • int precision, flags;
    • int precision, flags, colons; char padding; enum {LEFT, CHCASE, LOWER, UPPER, LOCALE_O, LOCALE_E}; #define BIT_OF(n) (1U<<(n)) @@ -348,6 +348,7 @@ rb_strftime_with_timespec(char *s, size_ precision = -1; flags = 0; padding = 0;
    • colons = 0; again: switch (*++format) { case '\0': @@ -530,13 +531,31 @@ rb_strftime_with_timespec(char *s, size_
      • us that muck around with various message processors. / case 'z': / time zone offset east of GMT e.g. -0600 */
    • if (precision < 4) precision = 4;
    • NEEDS(precision + 1);
    • switch (colons) {
    • case 0: /* %z -> +hhmm */
    • precision = precision <= 5 ? 2 : precision-3;
    • NEEDS(precision + 3);
    • break; +
    • case 1: /* %:z -> +hh:mm */
    • precision = precision <= 5 ? 2 : precision-3;
    • NEEDS(precision + 4);
    • break; +
    • case 2: /* %::z -> +hh:mm:ss */
    • precision = precision <= 5 ? 2 : precision-3;
    • NEEDS(precision + 7);
    • break; +
    • default:
    • format--;
    • goto unknown;
    • } if (gmt) { off = 0; } else {
    • off = NUM2LONG(rb_funcall(quo(vtm->utc_offset, INT2FIX(60)), rb_intern("round"), 0));
    • off = NUM2LONG(rb_funcall(vtm->utc_offset, rb_intern("round"), 0)); #if 0 #ifdef HAVE_TM_NAME /* @@ -583,11 +602,22 @@ rb_strftime_with_timespec(char *s, size_ } else { *s++ = '+'; }
    • off = off/60*100 + off%60;
    • i = snprintf(s, endp - s, (padding == ' ' ? "%*ld" : "%.*ld"),
    • precision - (precision > 4), off);
    • i = snprintf(s, endp - s, (padding == ' ' ? "%*ld" : "%.*ld"), precision, off / 3600);
    • if (i < 0) goto err;
    • s += i;
    • off = off % 3600;
    • if (1 <= colons)
    • *s++ = ':';
    • i = snprintf(s, endp - s, "%02d", off / 60); if (i < 0) goto err; s += i;
    • off = off % 60;
    • if (2 <= colons) {
    • *s++ = ':';
    • i = snprintf(s, endp - s, "%02d", off);
    • if (i < 0) goto err;
    • s += i;
    • } continue; #endif /* MAILHEADER_EXT */

@@ -839,6 +869,11 @@ rb_strftime_with_timespec(char *s, size_
padding = ' ';
goto again;

  • case ':':
  • FLAG_FOUND();
  • colons++;
  • goto again; + case '0': padding = '0'; case '1': case '2': case '3': case '4': -- [田中 哲][たなか あきら][Tanaka Akira] =end

History

#1

Updated by matz (Yukihiro Matsumoto) over 9 years ago

=begin
まつもと ゆきひろです

In message "Re: [ruby-dev:41841] [feature:trunk] %:z and %::z for strftime"
on Wed, 7 Jul 2010 21:53:26 +0900, Tanaka Akira akr@fsij.org writes:

|strftime で %:z と %::z という指定を可能にするのはどうでしょうか。
|
| % ./ruby -e 'p Time.now.strftime("%z %:z %::z")'
| "+0900 +09:00 +09:00:00"
|
|時差をフォーマットするのに現在は %z がありますが、これは +hhmm という形です。
|これは RFC 822 形式の時刻を表現するにはちょうどいいのですが、
|XML Schema や RFC 3339 や W3CDTF で使う、コロンが入った +hh:mm という
|形式とは合いません。
|
|そして、最近知ったのですが、GNU coreutils の date には %:z という指定で
|+hh:mm という形式を生成する機能があります。
|また、コロンをふたつにして %::z とすると +hh:mm:ss と秒まで生成します。
|
|というわけで、Ruby でも %:z と %::z をサポートするのはどうでしょう。
|
|なお、コロンが入った形式はその文字列自体を見て時刻の類であることがわかるので
|間違いが起きにくく、この型式はそれ自体良いものだと思います。

trunkになら入れてもいいんじゃないでしょうか。

=end

#2

Updated by akr (Akira Tanaka) over 9 years ago

  • Status changed from Open to Closed
  • % Done changed from 0 to 100

=begin
This issue was solved with changeset r28572.
Akira, thank you for reporting this issue.
Your contribution to Ruby is greatly appreciated.
May Ruby be with you.

=end

Also available in: Atom PDF