#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:
*/
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,
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;
#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;