[feature:trunk] %:z and %::z for strftime

strftime e$B$Ge(B %:z e$B$He(B %::z
e$B$H$$$&;XDj$r2DG=$K$9$k$N$O$I$&$G$7$g$&$+!#e(B

% ./ruby -e ‘p Time.now.strftime("%z %:z %::z")’
“+0900 +09:00 +09:00:00”

e$B;~:9$r%U%)!<%^%C%H$9$k$N$K8=:_$Oe(B %z e$B$,$"$j$^$9$,!"$3$l$Oe(B
+hhmm e$B$H$$$&7A$G$9!#e(B
e$B$3$l$Oe(B RFC 822
e$B7A<0$N;~9o$rI=8=$9$k$K$O$A$g$&$I$$$$$N$G$9$,!“e(B
XML Schema e$B$de(B RFC 3339 e$B$de(B W3CDTF
e$B$G;H$&!”%3%m%s$,F~$C$?e(B +hh:mm e$B$H$$$&e(B
e$B7A<0$H$O9g$$$^$;$s!#e(B

e$B$=$7$F!":G6aCN$C$?$N$G$9$,!“e(BGNU coreutils e$B$Ne(B date e$B$K$Oe(B
%:z e$B$H$$$&;XDj$Ge(B
+hh:mm e$B$H$$$&7A<0$r@8@.$9$k5!G=$,$”$j$^$9!#e(B
e$B$^$?!"%3%m%s$r$U$?$D$K$7$Fe(B %::z e$B$H$9$k$He(B +hh:mm:ss
e$B$HIC$^$G@8@.$7$^$9!#e(B

e$B$H$$$&$o$1$G!"e(BRuby e$B$G$be(B %:z e$B$He(B %::z
e$B$r%5%]!<%H$9$k$N$O$I$&$G$7$g$&!#e(B

e$B$J$*!"%3%m%s$,F~$C$?7A<0$O$=$NJ8;zNs<+BN$r8+$F;~9o$NN`$G$"$k$3$H$,$o$+$k$N$Ge(B
e$B4V0c$$$,5/$-$K$/$/!"$3$N7?<0$O$=$l<+BNNI$$$b$N$@$H;W$$$^$9!#e(B

% 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’:

e$B$^$D$b$He(B e$B$f$-$R$m$G$9e(B

In message “Re: [ruby-dev:41841] [feature:trunk] %:z and %::z for
strftime”
on Wed, 7 Jul 2010 21:53:26 +0900, Tanaka A. [email protected]
writes:

|strftime e$B$Ge(B %:z e$B$He(B %::z e$B$H$$$&;XDj$r2DG=$K$9$k$N$O$I$&$G$7$g$&$+!#e(B
|
| % ./ruby -e ‘p Time.now.strftime(“%z %:z %::z”)’
| “+0900 +09:00 +09:00:00”
|
|e$B;~:9$r%U%)!<%^%C%H$9$k$N$K8=:_$Oe(B %z e$B$,$“$j$^$9$,!”$3$l$Oe(B +hhmm e$B$H$$$&7A$G$9!#e(B
|e$B$3$l$Oe(B RFC 822 e$B7A<0$N;~9o$rI=8=$9$k$K$O$A$g$&$I$$$$$N$G$9$,!“e(B
|XML Schema e$B$de(B RFC 3339 e$B$de(B W3CDTF e$B$G;H$&!”%3%m%s$,F~$C$?e(B +hh:mm e$B$H$$$&e(B
|e$B7A<0$H$O9g$$$^$;$s!#e(B
|
|e$B$=$7$F!“:G6aCN$C$?$N$G$9$,!“e(BGNU coreutils e$B$Ne(B date e$B$K$Oe(B %:z e$B$H$$$&;XDj$Ge(B
|+hh:mm e$B$H$$$&7A<0$r@8@.$9$k5!G=$,$”$j$^$9!#e(B
|e$B$^$?!”%3%m%s$r$U$?$D$K$7$Fe(B %::z e$B$H$9$k$He(B +hh:mm:ss e$B$HIC$^$G@8@.$7$^$9!#e(B
|
|e$B$H$$$&$o$1$G!“e(BRuby e$B$G$be(B %:z e$B$He(B %::z e$B$r%5%]!<%H$9$k$N$O$I$&$G$7$g$&!#e(B
|
|e$B$J$*!”%3%m%s$,F~$C$?7A<0$O$=$NJ8;zNs<+BN$r8+$F;~9o$NN`$G$“$k$3$H$,$o$+$k$N$Ge(B
|e$B4V0c$$$,5/$-$K$/$/!”$3$N7?<0$O$=$l<+BNNI$$$b$N$@$H;W$$$^$9!#e(B

trunke$B$K$J$iF~$l$F$b$$$$$s$8$c$J$$$G$7$g$&$+!#e(B

e$B%A%1%C%He(B #3547 e$B$,99?7$5$l$^$7$?!#e(B (by Akira T.)

e$B%9%F!<%?%9e(B Opene$B$+$ie(BClosede$B$KJQ99e(B
e$B?JD=e(B % 0e$B$+$ie(B100e$B$KJQ99e(B

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.


http://redmine.ruby-lang.org/issues/show/3547