diff --git a/api/soap/mc_api.php b/api/soap/mc_api.php index f03ec526a9..76089d197d 100644 --- a/api/soap/mc_api.php +++ b/api/soap/mc_api.php @@ -208,11 +208,13 @@ static function objectToArray( $p_object, $p_recursive = false ) { } /** - * Convert a timestamp to a soap DateTime variable - * @param integer $p_value Integer value to return as date time string. - * @return datetime in expected API format. + * Convert a timestamp to a soap DateTime variable or ISO-8601 date. + * + * @param int $p_value Unix Timestamp. + * + * @return SoapVar|string datetime in expected API format. */ - static function datetime($p_value ) { + static function datetime( $p_value ) { $t_string_value = self::datetimeString( $p_value ); if( ApiObjectFactory::$soap ) { @@ -223,16 +225,27 @@ static function datetime($p_value ) { } /** - * Convert a timestamp to a DateTime string - * @param integer $p_timestamp Integer value to format as date time string. - * @return string for provided timestamp + * Convert a timestamp to an ISO-8601 formatted DateTime string. + * + * @param int|null $p_timestamp Unix timestamp. + * + * @return string|null Formatted datetime. */ - static function datetimeString($p_timestamp ) { - if( $p_timestamp == null || date_is_null( $p_timestamp ) ) { - return null; - } + static function datetimeString( $p_timestamp ) { + return date_timestamp_to_iso8601( $p_timestamp ); + } - return date( 'c', (int)$p_timestamp ); + /** + * Converts a datetime string to a Unix timestamp. + * + * @param string $p_date_string Date string. + * + * @return int|null Unix timestamp, null when $p_date_string is blank. + * + * @throws ClientException When given string cannot be converted to Date. + */ + static function dateStringToTimestamp( $p_date_string ): ?int { + return date_string_to_timestamp( $p_date_string ); } /** diff --git a/core/commands/VersionAddCommand.php b/core/commands/VersionAddCommand.php index fc81254322..ee9bd9c022 100644 --- a/core/commands/VersionAddCommand.php +++ b/core/commands/VersionAddCommand.php @@ -80,10 +80,8 @@ function validate() { array( 'name' ) ); } - $t_timestamp = $this->payload( 'timestamp', '' ); - $this->timestamp = is_blank( $t_timestamp ) - ? null - : ( is_int( $t_timestamp ) ? $t_timestamp : strtotime( $t_timestamp ) ); + $t_date_string = $this->payload( 'timestamp', '' ); + $this->timestamp = date_string_to_timestamp( $t_date_string ); } /** diff --git a/core/commands/VersionUpdateCommand.php b/core/commands/VersionUpdateCommand.php index 64f20332f7..15dc8e13d8 100644 --- a/core/commands/VersionUpdateCommand.php +++ b/core/commands/VersionUpdateCommand.php @@ -153,12 +153,9 @@ protected function process() { $t_version->obsolete = $t_obsolete; } - $t_timestamp = $this->payload( 'timestamp' ); - if( !is_blank( $t_timestamp ) ) { - if( !is_int( $t_timestamp ) ) { - $t_timestamp = strtotime( $t_timestamp ); - } - $t_version->date_order = $t_timestamp; + $t_date_string = $this->payload( 'timestamp' ); + if( !is_blank( $t_date_string ) ) { + $t_version->date_order = date_string_to_timestamp( $t_date_string ); } version_update( $t_version ); diff --git a/core/date_api.php b/core/date_api.php index 01b00fa318..b1bb7a9743 100644 --- a/core/date_api.php +++ b/core/date_api.php @@ -65,6 +65,54 @@ function date_get_null() { return 1; } + +/** + * Converts a datetime string to a Unix timestamp. + * + * @param string $p_date_string Date string. + * + * @return int|null Unix timestamp, null when $p_date_string is blank. + * + * @throws ClientException When given string cannot be converted to Date. + */ +function date_string_to_timestamp( string $p_date_string ): ?int { + if( is_blank( $p_date_string ) ) { + return null; + } + + # @TODO if we ever decide to require strict ISO-8601 date formatting in the + # future, this should be enforced here. + + try { + $t_dt = new DateTimeImmutable( $p_date_string ); + } + catch( Exception $e ) { + throw new ClientException( + "Invalid date format '$p_date_string'", + ERROR_INVALID_DATE_FORMAT, + array( $p_date_string ), + $e + ); + } + return $t_dt->getTimestamp(); +} + +/** + * Converts a timestamp to an ISO-8601 formatted date. + * + * @param int|null $p_timestamp Unix Timestamp. + * + * @return string|null ISO-8601 formatted date. + */ +function date_timestamp_to_iso8601( ?int $p_timestamp ): ?string { + if( $p_timestamp == null || date_is_null( $p_timestamp ) ) { + return null; + } + + return date( 'c', (int)$p_timestamp ); +} + + /** * Gets Unix timestamp from a date string. * @@ -87,21 +135,12 @@ function date_strtotime( $p_date_string ) { $t_format = config_get( 'normal_date_format' ); $t_dt = DateTimeImmutable::createFromFormat( $t_format, $p_date_string ); - if( $t_dt === false ) { - # date is not in expected format, try with default formats - try { - $t_dt = new DateTimeImmutable( $p_date_string ); - } - catch( Exception $e ) { - throw new ClientException( - "Invalid date format '$p_date_string'", - ERROR_INVALID_DATE_FORMAT, - array( $p_date_string ), - $e - ); - } + if( $t_dt !== false ) { + return $t_dt->getTimestamp(); } - return $t_dt->getTimestamp(); + + # date is not in expected format, try with default formats + return date_string_to_timestamp( $p_date_string ); } /** diff --git a/manage_proj_ver_update.php b/manage_proj_ver_update.php index c5c86955c2..bbdd5b6a49 100644 --- a/manage_proj_ver_update.php +++ b/manage_proj_ver_update.php @@ -52,6 +52,7 @@ $f_new_version = trim( $f_new_version ); $t_version = version_get( $f_version_id ); +$t_timestamp = date_strtotime( $f_date_order ); $t_data = array( 'query' => array( @@ -63,7 +64,7 @@ 'description' => $f_description, 'released' => $f_released, 'obsolete' => $f_obsolete, - 'timestamp' => date_strtotime( $f_date_order ) + 'timestamp' => date_timestamp_to_iso8601( $t_timestamp ), ) );