It seems you have a more serious problem than just date formatting: because they are standardized or standardized in a single type/input format.
As this does not fit the scope of the topic, if I have assumed correctly, the solution presented by Zuul, although correct from the programmatic point of view, is not enough because it takes into account a single date format.
Therefore, I offer the function below, created by a forum friend introduced here in the community on another topic:
/**
* Altera uma data para outro formato
*
* @param string $date String contendo a data a ser formatada
* @param string $outputFormat Formato de saida
* @throws Exception Quando não puder converter a data
* @return string Data formatada
* @author Hugo Ferreira da Silva
*/
function parseDate($date, $outputFormat = 'd/m/Y'){
$formats = array(
'd/m/Y',
'd/m/Y H',
'd/m/Y H:i',
'd/m/Y H:i:s',
'Y-m-d',
'Y-m-d H',
'Y-m-d H:i',
'Y-m-d H:i:s',
);
foreach($formats as $format){
$dateObj = DateTime::createFromFormat($format, $date);
if($dateObj !== false){
break;
}
}
if($dateObj === false){
throw new Exception('Invalid date:' . $date);
}
return $dateObj->format($outputFormat);
}
For testing:
$testDates = array(
'2012-10-30 00:00:00',
'06/01/1986 14',
'06/12/1983 14:30:10',
'1984-01-06 14:30:10',
);
foreach($testDates as $date){
var_dump( parseDate($date, 'Y-m-d') );
//var_dump( DateTime::createFromFormat('d/m/Y', $date) instanceof DateTime );
}
Exit:
string '2012-10-30' (length=10)
string '1986-01-06' (length=10)
string '1983-12-06' (length=10)
string '1984-01-06' (length=10)
Just to illustrate why the solution of friend Zuul is not enough to experiment with this same array of random dates to create a Datetime object without change the format:
foreach($testDates as $date){
var_dump( DateTime::createFromFormat('d/m/Y', $date) instanceof DateTime );
}
All four iterations result in FALSE because none of them are in format d/m/Y whereas the function presented here takes into account the eight main date/time formats.
As explained in the comments of this answer the function presented here makes return 11/12/2014 2014 2014-12-11 that although valid programmatically does not compute with the required logic.
This is because primarily the function takes into account dates in the Brazilian DAY/MONTH/YEAR format and as the foreach
is stopped when a format creates a Datetime object successfully results in a false positive.
The solution is quite simple, just reorder the array $formats in the way that suits you best.
For example:
$formats = array(
'Y-m-d',
'Y-m-d H',
'Y-m-d H:i',
'Y-m-d H:i:s',
'd/m/Y',
'd/m/Y H',
'd/m/Y H:i',
'd/m/Y H:i:s',
);
Already makes it 11/12/2014 return 2014-12-11 and 30/10/2014 return 2014-10-30.
One more consideration:
Just as you can and should reorder the format array as you think best you can also include new formats specific to your need.
Since the first of your dates is in a format valid for a date but not considered in the available formats (m/d/Y), just add it to the array:
$formats = array(
'm/d/Y', // <---
'Y-m-d',
'Y-m-d H',
'Y-m-d H:i',
'Y-m-d H:i:s',
'd/m/Y',
'd/m/Y H',
'd/m/Y H:i',
'd/m/Y H:i:s',
);
But bear in mind that both this solution and the one proposed by Zuul will fail according to the logic you expect because your dates are not normalized.
As far as I know there is no way to automatically detect whether a given component of a date is a day, a month or a year.
Putting the new format m/d/Y at the beginning of $formats will return what is expected for the first date. But for the second return 2016-06-10, which I imagine to be a problem of Datetime itself because there is no month 30.
Other ways to convert: http://answall.com/q/21774/91
– rray
Unfortunately it is impossible to determine exactly what kind of date you are receiving when they are ambiguous... You will have to choose which type should be considered the standard... (Checking which one occurs most often)
– Jader A. Wagner
The problem when storing in the database is due to what has already been discussed in the answers. However, you should not add problems to your current question because the answers are no longer valid, you should open a new question to deal with the database problem.
– Zuul
@Zuul done, thank you
– smigol