Basically, in XMP you can specify partial date (for example 2011-04 for april 2011 with no day).
We were extracting that, and fulling out the day to 01 if it wasn't present (My original resoning when writing
the code was that the nice localized date functions need a full date, but that's a pretty poor rationale for displaying
wrong date). This changes it to just display such year-month things as YYYY:MM.
if ( $val == '0000:00:00 00:00:00' || $val == ' : : : : ' ) {
$val = wfMsg( 'exif-unknowndate' );
} elseif ( preg_match( '/^(?:\d{4}):(?:\d\d):(?:\d\d) (?:\d\d):(?:\d\d):(?:\d\d)$/D', $val ) ) {
+ // Full date.
$time = wfTimestamp( TS_MW, $val );
if ( $time && intval( $time ) > 0 ) {
$val = $wgLang->timeanddate( $time );
}
+ } elseif ( preg_match( '/^(?:\d{4}):(?:\d\d):(?:\d\d) (?:\d\d):(?:\d\d)$/D', $val ) ) {
+ // No second field. Still format the same
+ // since timeanddate doesn't include seconds anyways,
+ // but second still available in api
+ $time = wfTimestamp( TS_MW, $val . ':00' );
+ if ( $time && intval( $time ) > 0 ) {
+ $val = $wgLang->timeanddate( $time );
+ }
} elseif ( preg_match( '/^(?:\d{4}):(?:\d\d):(?:\d\d)$/D', $val ) ) {
// If only the date but not the time is filled in.
$time = wfTimestamp( TS_MW, substr( $val, 0, 4 )
}
/**
- * function to validate date properties, and convert to Exif format.
+ * function to validate date properties, and convert to (partial) Exif format.
+ *
+ * Dates can be one of the following formats:
+ * YYYY
+ * YYYY-MM
+ * YYYY-MM-DD
+ * YYYY-MM-DDThh:mmTZD
+ * YYYY-MM-DDThh:mm:ssTZD
+ * YYYY-MM-DDThh:mm:ss.sTZD
*
* @param $info Array information about current property
* @param &$val Mixed current value to validate. Converts to TS_EXIF as a side-effect.
+ * in cases where there's only a partial date, it will give things like
+ * 2011:04.
* @param $standalone Boolean if this is a simple property or array
*/
public static function validateDate( $info, &$val, $standalone ) {
$val = null;
return;
}
- //if month, etc unspecified, full out as 01.
- $res[2] = isset( $res[2] ) ? $res[2] : '01'; //month
- $res[3] = isset( $res[3] ) ? $res[3] : '01'; //day
+
if ( !isset( $res[4] ) ) { //hour
- //just have the year month day
- $val = $res[1] . ':' . $res[2] . ':' . $res[3];
+ //just have the year month day (if that)
+ $val = $res[1];
+ if ( isset( $res[2] ) ) {
+ $val .= ':' . $res[2];
+ }
+ if ( isset( $res[3] ) ) {
+ $val .= ':' . $res[3];
+ }
return;
}
- //if hour is set, so is minute or regex above will fail.
- //Extra check for empty string necessary due to TZ but no second case.
- $res[6] = isset( $res[6] ) && $res[6] != '' ? $res[6] : '00';
if ( !isset( $res[7] ) || $res[7] === 'Z' ) {
+ //if hour is set, then minute must also be or regex above will fail.
$val = $res[1] . ':' . $res[2] . ':' . $res[3]
- . ' ' . $res[4] . ':' . $res[5] . ':' . $res[6];
+ . ' ' . $res[4] . ':' . $res[5];
+ if ( isset( $res[6] ) && $res[6] !== '' ) {
+ $val .= ':' . $res[6];
+ }
return;
}
- //do timezone processing. We've already done the case that tz = Z.
+
+ // Extra check for empty string necessary due to TZ but no second case.
+ $stripSeconds = false;
+ if ( !isset( $res[6] ) || $res[6] === '' ) {
+ $res[6] = '00';
+ $stripSeconds = true;
+ }
+
+ // Do timezone processing. We've already done the case that tz = Z.
+
+ // We know that if we got to this step, year, month day hour and min must be set
+ // by virtue of regex not failing.
$unix = wfTimestamp( TS_UNIX, $res[1] . $res[2] . $res[3] . $res[4] . $res[5] . $res[6] );
$offset = intval( substr( $res[7], 1, 2 ) ) * 60 * 60;
$offset = -$offset;
}
$val = wfTimestamp( TS_EXIF, $unix + $offset );
+
+ if ( $stripSeconds ) {
+ // If seconds weren't specified, remove the trailing ':00'.
+ $val = substr( $val, 0, -3 );
+ }
}
}
--- /dev/null
+<?php
+class XMPTest extends MediaWikiTestCase {
+
+ /**
+ * @dataProvider providerDate
+ */
+ function testValidateDate( $value, $expected ) {
+ // The method should modify $value.
+ XMPValidate::validateDate( array(), $value, true );
+ $this->assertEquals( $expected, $value );
+ }
+
+ function providerDate() {
+ /* For reference valid date formats are:
+ * YYYY
+ * YYYY-MM
+ * YYYY-MM-DD
+ * YYYY-MM-DDThh:mmTZD
+ * YYYY-MM-DDThh:mm:ssTZD
+ * YYYY-MM-DDThh:mm:ss.sTZD
+ * (Time zone is optional)
+ */
+ return array(
+ array( '1992', '1992' ),
+ array( '1992-04', '1992:04' ),
+ array( '1992-02-01', '1992:02:01' ),
+ array( '2011-09-29', '2011:09:29' ),
+ array( '1982-12-15T20:12', '1982:12:15 20:12' ),
+ array( '1982-12-15T20:12Z', '1982:12:15 20:12' ),
+ array( '1982-12-15T20:12+02:30', '1982:12:15 22:42' ),
+ array( '1982-12-15T01:12-02:30', '1982:12:14 22:42' ),
+ array( '1982-12-15T20:12:11', '1982:12:15 20:12:11' ),
+ array( '1982-12-15T20:12:11Z', '1982:12:15 20:12:11' ),
+ array( '1982-12-15T20:12:11+01:10', '1982:12:15 21:22:11' ),
+ array( '2045-12-15T20:12:11', '2045:12:15 20:12:11' ),
+ array( '1867-06-01T15:00:00', '1867:06:01 15:00:00' ),
+ /* some invalid ones */
+ array( '2001--12', null ),
+ array( '2001-5-12', null ),
+ array( '2001-5-12TZ', null ),
+ array( '2001-05-12T15', null ),
+ array( '2001-12T15:13', null ),
+ );
+
+ }
+
+}