public function setTimestamp( $ts = false ) {
		$m = [];
		$da = [];
		$strtime = '';

		// We want to catch 0, '', null... but not date strings starting with a letter.
		if ( !$ts || $ts === "\0\0\0\0\0\0\0\0\0\0\0\0\0\0" ) {
			$uts = self::time();
			$strtime = "@$uts";
		} elseif ( preg_match( '/^(\d{4})\-(\d\d)\-(\d\d) (\d\d):(\d\d):(\d\d)$/D', $ts, $da ) ) {
			# TS_DB
		} elseif ( preg_match( '/^(\d{4}):(\d\d):(\d\d) (\d\d):(\d\d):(\d\d)$/D', $ts, $da ) ) {
			# TS_EXIF
		} elseif ( preg_match( '/^(\d{4})(\d\d)(\d\d)(\d\d)(\d\d)(\d\d)$/D', $ts, $da ) ) {
			# TS_MW
		} elseif ( preg_match( '/^(-?\d{1,13})$/D', $ts, $m ) ) {
			# TS_UNIX
			$strtime = "@{$m[1]}"; // http://php.net/manual/en/datetime.formats.compound.php
		} elseif ( preg_match( '/^(-?\d{1,13})(\.\d+)$/D', $ts, $m ) ) {
			# TS_UNIX_MICRO
			// Not supported with @, so we need a hack
			$strtime = 'unixmicro';
		} elseif ( preg_match( '/^\d{2}-\d{2}-\d{4} \d{2}:\d{2}:\d{2}.\d{6}$/', $ts ) ) {
			# TS_ORACLE // session altered to DD-MM-YYYY HH24:MI:SS.FF6
			$strtime = preg_replace( '/(\d\d)\.(\d\d)\.(\d\d)(\.(\d+))?/', "$1:$2:$3",
				str_replace( '+00:00', 'UTC', $ts ) );
		} elseif ( preg_match(
			'/^(\d{4})-(\d{2})-(\d{2})T(\d{2}):(\d{2}):(\d{2})(?:\.*\d*)?Z?$/',
			$ts,
			$da
		) ) {
			# TS_ISO_8601
		} elseif ( preg_match(
			'/^(\d{4})(\d{2})(\d{2})T(\d{2})(\d{2})(\d{2})(?:\.*\d*)?Z?$/',
			$ts,
			$da
		) ) {
			# TS_ISO_8601_BASIC
		} elseif ( preg_match(
			'/^(\d{4})\-(\d\d)\-(\d\d) (\d\d):(\d\d):(\d\d)\.*\d*[\+\- ](\d\d)$/',
			$ts,
			$da
		) ) {
			# TS_POSTGRES
		} elseif ( preg_match(
			'/^(\d{4})\-(\d\d)\-(\d\d) (\d\d):(\d\d):(\d\d)\.*\d* GMT$/',
			$ts,
			$da
		) ) {
			# TS_POSTGRES
		} elseif ( preg_match(
			# Day of week
			'/^[ \t\r\n]*([A-Z][a-z]{2},[ \t\r\n]*)?' .
			# dd Mon yyyy
			'\d\d?[ \t\r\n]*[A-Z][a-z]{2}[ \t\r\n]*\d{2}(?:\d{2})?' .
			# hh:mm:ss
			'[ \t\r\n]*\d\d[ \t\r\n]*:[ \t\r\n]*\d\d[ \t\r\n]*:[ \t\r\n]*\d\d/S',
			$ts
		) ) {
			# TS_RFC2822, accepting a trailing comment.
			# See http://www.squid-cache.org/mail-archive/squid-users/200307/0122.html / r77171
			# The regex is a superset of rfc2822 for readability
			$strtime = strtok( $ts, ';' );
		} elseif ( preg_match( '/^[A-Z][a-z]{5,8}, \d\d-[A-Z][a-z]{2}-\d{2} \d\d:\d\d:\d\d/', $ts ) ) {
			# TS_RFC850
			$strtime = $ts;
		} elseif ( preg_match( '/^[A-Z][a-z]{2} [A-Z][a-z]{2} +\d{1,2} \d\d:\d\d:\d\d \d{4}/', $ts ) ) {
			# asctime
			$strtime = $ts;
		} else {
			throw new TimestampException( __METHOD__ . ": Invalid timestamp - $ts" );
		}

		if ( !$strtime ) {
			$da = array_map( 'intval', $da );
			$da[0] = "%04d-%02d-%02dT%02d:%02d:%02d.00+00:00";
			$strtime = call_user_func_array( "sprintf", $da );
		}

		try {
			if ( $strtime === 'unixmicro' ) {
				$final = DateTime::createFromFormat( 'U.u', $ts, new DateTimeZone( 'GMT' ) );
			} else {
				$final = new DateTime( $strtime, new DateTimeZone( 'GMT' ) );
			}
		} catch ( Exception $e ) {
			throw new TimestampException( __METHOD__ . ': Invalid timestamp format.', $e->getCode(), $e );
		}

		if ( $final === false ) {
			throw new TimestampException( __METHOD__ . ': Invalid timestamp format.' );
		}

		$this->timestamp = $final;
	}