Attempt to prefer user's date format when parsing date from a string.

Should fix merging into spreadsheet problems with certain date formats (dd/mm/yyyy)
This commit is contained in:
nathangray 2018-02-02 11:37:02 -07:00
parent b3fa7832a2
commit 8231f44ce2
2 changed files with 53 additions and 29 deletions

View File

@ -467,7 +467,8 @@ class DateTime extends \DateTime
{
try
{
$time = new DateTime($time);
// Try user format first
$time = static::createFromUserFormat($time);
}
catch(\Exception $e)
{
@ -478,6 +479,56 @@ class DateTime extends \DateTime
return $time->format($type);
}
/**
* Some user formats are conflicting and cannot be reliably parsed by the
* normal means. Here we agressively try various date formats (based on
* user's date preference) to coerce a troublesome date into a DateTime.
*
* ex: 07/08/2018 could be DD/MM/YYYY or MM/DD/YYYY
*
* Rather than trust DateTime to guess right based on its settings, we use
* the user's date preference to resolve the ambiguity.
*
* @param string $time
* @return DateTime or null
*/
public static function createFromUserFormat($time)
{
$date = null;
// If numeric, just let normal constructor do it
if(is_numeric($time))
{
return new DateTime($time);
}
// Various date formats in decreasing preference
$formats = array(
'!'.static::$user_dateformat . ' ' .static::$user_timeformat.':s',
'!'.static::$user_dateformat . '*' .static::$user_timeformat.':s',
'!'.static::$user_dateformat . '* ' .static::$user_timeformat,
'!'.static::$user_dateformat . '*',
'!'.static::$user_dateformat,
'!Y-m-d\TH:i:s'
);
// Try the different formats, stop when one works
foreach($formats as $f)
{
try {
$date = static::createFromFormat(
$f,
$time,
static::$user_timezone
);
if($date) break;
} catch (\Exception $e) {
}
}
// Need correct class, createFromFormat() gives parent
return new DateTime($date ? $date : $time);
}
/**
* Setter for user timezone, should be called after reading user preferences
*

View File

@ -1287,34 +1287,7 @@ abstract class Merge
$field = preg_quote($field, '/');
if($values[$key])
{
if(!is_numeric($values[$key]))
{
// Try the different formats, stop when one works
foreach($formats as $f)
{
try {
$date = Api\DateTime::createFromFormat(
$f,
$values[$key],
Api\DateTime::$user_timezone
);
if($date) break;
} catch (\Exception $e) {
}
}
if(!$date)
{
// Couldn't get a date out of it... skip it
trigger_error("Unable to parse date $key = '{$values[$key]}' - left as text", E_USER_NOTICE);
unset($names[$idx]);
continue;
}
}
else
{
$date = new Api\DateTime($values[$key]);
}
$date = Api\DateTime::createFromUserFormat($values[$key]);
if($mimetype == 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet' ||
$mimetype == 'application/vnd.ms-excel.sheet.macroenabled.12')//Excel WTF
{