]> granicus.if.org Git - php/commitdiff
Adding 'v' formatting to DateTime::format(), and adding constant DateTime::RFC3339_EX...
authorMariano Iglesias <mariano@cricava.com>
Thu, 19 Feb 2015 15:46:00 +0000 (12:46 -0300)
committerMariano Iglesias <mariano@cricava.com>
Fri, 20 Feb 2015 12:21:14 +0000 (09:21 -0300)
ext/date/php_date.c
ext/date/tests/DateTime_verify.phpt
ext/date/tests/rfc-datetime_rfc3339_extended.phpt [new file with mode: 0644]

index 819b1732f3696359d438db8eb178492abc30755f..4b6deaf648873bed9cd215b8b8b8fd6b4eaad398 100644 (file)
@@ -809,6 +809,16 @@ PHP_RSHUTDOWN_FUNCTION(date)
 
 #define DATE_FORMAT_ISO8601  "Y-m-d\\TH:i:sO"
 
+/*
+ * RFC3339, Appendix A: http://www.ietf.org/rfc/rfc3339.txt
+ *  ISO 8601 also requires (in section 5.3.1.3) that a decimal fraction
+ *  be proceeded by a "0" if less than unity.  Annex B.2 of ISO 8601
+ *  gives examples where the decimal fractions are not preceded by a "0".
+ *  This grammar assumes section 5.3.1.3 is correct and that Annex B.2 is
+ *  in error.
+ */
+#define DATE_FORMAT_RFC3339_EXTENDED  "Y-m-d\\TH:i:s.vP"
+
 /*
  * This comes from various sources that like to contradict. I'm going with the
  * format here because of:
@@ -849,12 +859,15 @@ PHP_MINIT_FUNCTION(date)
  */
        REGISTER_STRING_CONSTANT("DATE_COOKIE",  DATE_FORMAT_COOKIE,  CONST_CS | CONST_PERSISTENT);
        REGISTER_STRING_CONSTANT("DATE_ISO8601", DATE_FORMAT_ISO8601, CONST_CS | CONST_PERSISTENT);
+
        REGISTER_STRING_CONSTANT("DATE_RFC822",  DATE_FORMAT_RFC822,  CONST_CS | CONST_PERSISTENT);
        REGISTER_STRING_CONSTANT("DATE_RFC850",  DATE_FORMAT_RFC850,  CONST_CS | CONST_PERSISTENT);
        REGISTER_STRING_CONSTANT("DATE_RFC1036", DATE_FORMAT_RFC1036, CONST_CS | CONST_PERSISTENT);
        REGISTER_STRING_CONSTANT("DATE_RFC1123", DATE_FORMAT_RFC1123, CONST_CS | CONST_PERSISTENT);
        REGISTER_STRING_CONSTANT("DATE_RFC2822", DATE_FORMAT_RFC2822, CONST_CS | CONST_PERSISTENT);
-       REGISTER_STRING_CONSTANT("DATE_RFC3339", DATE_FORMAT_RFC3339, CONST_CS | CONST_PERSISTENT);
+       REGISTER_STRING_CONSTANT("DATE_RFC3339", DATE_FORMAT_RFC3339, CONST_CS | CONST_PERSISTENT);
+       REGISTER_STRING_CONSTANT("DATE_RFC3339_EXTENDED", DATE_FORMAT_RFC3339_EXTENDED, CONST_CS | CONST_PERSISTENT);
+
 /*
  * RSS 2.0 Specification: http://blogs.law.harvard.edu/tech/rss
  *   "All date-times in RSS conform to the Date and Time Specification of RFC 822,
@@ -1145,6 +1158,7 @@ static zend_string *date_format(char *format, size_t format_len, timelib_time *t
                        case 'i': length = slprintf(buffer, 32, "%02d", (int) t->i); break;
                        case 's': length = slprintf(buffer, 32, "%02d", (int) t->s); break;
                        case 'u': length = slprintf(buffer, 32, "%06d", (int) floor(t->f * 1000000 + 0.5)); break;
+                       case 'v': length = slprintf(buffer, 32, "%03d", (int) floor(t->f * 1000 + 0.5)); break;
 
                        /* timezone */
                        case 'I': length = slprintf(buffer, 32, "%d", localtime ? offset->is_dst : 0); break;
@@ -1981,17 +1995,18 @@ static void date_register_classes(void) /* {{{ */
 #define REGISTER_DATE_CLASS_CONST_STRING(const_name, value) \
        zend_declare_class_constant_stringl(date_ce_date, const_name, sizeof(const_name)-1, value, sizeof(value)-1);
 
-       REGISTER_DATE_CLASS_CONST_STRING("ATOM",    DATE_FORMAT_RFC3339);
-       REGISTER_DATE_CLASS_CONST_STRING("COOKIE",  DATE_FORMAT_COOKIE);
-       REGISTER_DATE_CLASS_CONST_STRING("ISO8601", DATE_FORMAT_ISO8601);
-       REGISTER_DATE_CLASS_CONST_STRING("RFC822",  DATE_FORMAT_RFC822);
-       REGISTER_DATE_CLASS_CONST_STRING("RFC850",  DATE_FORMAT_RFC850);
-       REGISTER_DATE_CLASS_CONST_STRING("RFC1036", DATE_FORMAT_RFC1036);
-       REGISTER_DATE_CLASS_CONST_STRING("RFC1123", DATE_FORMAT_RFC1123);
-       REGISTER_DATE_CLASS_CONST_STRING("RFC2822", DATE_FORMAT_RFC2822);
-       REGISTER_DATE_CLASS_CONST_STRING("RFC3339", DATE_FORMAT_RFC3339);
-       REGISTER_DATE_CLASS_CONST_STRING("RSS",     DATE_FORMAT_RFC1123);
-       REGISTER_DATE_CLASS_CONST_STRING("W3C",     DATE_FORMAT_RFC3339);
+       REGISTER_DATE_CLASS_CONST_STRING("ATOM",             DATE_FORMAT_RFC3339);
+       REGISTER_DATE_CLASS_CONST_STRING("COOKIE",           DATE_FORMAT_COOKIE);
+       REGISTER_DATE_CLASS_CONST_STRING("ISO8601",          DATE_FORMAT_ISO8601);
+       REGISTER_DATE_CLASS_CONST_STRING("RFC822",           DATE_FORMAT_RFC822);
+       REGISTER_DATE_CLASS_CONST_STRING("RFC850",           DATE_FORMAT_RFC850);
+       REGISTER_DATE_CLASS_CONST_STRING("RFC1036",          DATE_FORMAT_RFC1036);
+       REGISTER_DATE_CLASS_CONST_STRING("RFC1123",          DATE_FORMAT_RFC1123);
+       REGISTER_DATE_CLASS_CONST_STRING("RFC2822",          DATE_FORMAT_RFC2822);
+       REGISTER_DATE_CLASS_CONST_STRING("RFC3339",          DATE_FORMAT_RFC3339);
+       REGISTER_DATE_CLASS_CONST_STRING("RFC3339_EXTENDED", DATE_FORMAT_RFC3339_EXTENDED);
+       REGISTER_DATE_CLASS_CONST_STRING("RSS",              DATE_FORMAT_RFC1123);
+       REGISTER_DATE_CLASS_CONST_STRING("W3C",              DATE_FORMAT_RFC3339);
 
        INIT_CLASS_ENTRY(ce_immutable, "DateTimeImmutable", date_funcs_immutable);
        ce_immutable.create_object = date_object_new_date;
index 95aa37a5261f6e002cff94db2c241624187b0aed..33768969dc1bd9c2db7fe8c430e47748f4de7def 100644 (file)
@@ -156,7 +156,7 @@ array(18) {
   }
 }
 ..and get names of all its class constants
-array(11) {
+array(12) {
   ["ATOM"]=>
   string(13) "Y-m-d\TH:i:sP"
   ["COOKIE"]=>
@@ -175,6 +175,8 @@ array(11) {
   string(16) "D, d M Y H:i:s O"
   ["RFC3339"]=>
   string(13) "Y-m-d\TH:i:sP"
+  ["RFC3339_EXTENDED"]=>
+  string(15) "Y-m-d\TH:i:s.vP"
   ["RSS"]=>
   string(16) "D, d M Y H:i:s O"
   ["W3C"]=>
diff --git a/ext/date/tests/rfc-datetime_rfc3339_extended.phpt b/ext/date/tests/rfc-datetime_rfc3339_extended.phpt
new file mode 100644 (file)
index 0000000..5235aa6
--- /dev/null
@@ -0,0 +1,17 @@
+--TEST--
+RFC: DateTime RFC3339 Extended
+--CREDITS--
+Mariano Iglesias <mariano@cricava.com>
+--FILE--
+<?php
+date_default_timezone_set('America/Buenos_Aires');
+
+$date = new DateTime('2009-09-28 09:45:31.918312');
+
+var_dump($date->format(DateTime::RFC3339_EXTENDED));
+var_dump($date->format('u'));
+var_dump($date->format('v'));
+--EXPECT--
+string(29) "2009-09-28T09:45:31.918-03:00"
+string(6) "918312"
+string(3) "918"