$hour24 = (int) substr($dateString, 11, 2);
$minute = (int) substr($dateString, 14, 2);
+ $second = (int) substr($dateString, 17, 2);
}
else {
$year = (int) substr($dateString, 0, 4);
$hour24 = (int) substr($dateString, 8, 2);
$minute = (int) substr($dateString, 10, 2);
+ $second = (int) substr($dateString, 12, 2);
}
if ($day % 10 == 1 and $day != 11) {
'%P' => $type,
'%A' => $type,
'%Y' => $year,
+ '%s' => str_pad($second, 2, 0, STR_PAD_LEFT),
];
return strtr($format, $date);
}
- else {
- return '';
- }
+ return '';
}
/**
}
/**
+ * Date formatting for imports where date format is specified.
+ *
+ * Note this is used for imports (only) because the importer can
+ * specify the format.
+ *
+ * Tests are in CRM_Utils_DateTest::testFormatDate
+ *
* @param $date
+ * Date string as entered.
* @param $dateType
+ * One of the constants like CRM_Core_Form_Date::DATE_yyyy_mm_dd.
*
* @return null|string
*/
public static function formatDate($date, $dateType) {
- $formattedDate = NULL;
if (empty($date)) {
- return $formattedDate;
+ return NULL;
}
// 1. first convert date to default format.
if (CRM_Utils_Date::convertToDefaultDate($dateParams, $dateType, $dateKey)) {
$dateVal = $dateParams[$dateKey];
- $ruleName = 'date';
if ($dateType == 1) {
$matches = [];
- if (preg_match("/(\s(([01]\d)|[2][0-3]):([0-5]\d))$/", $date, $matches)) {
- $ruleName = 'dateTime';
+ // The seconds part of this regex is not quite right - but it does succeed
+ // in clarifying whether there is a time component or not - which is all it is meant
+ // to do.
+ if (preg_match('/(\s(([01]\d)|[2][0-3]):([0-5]\d):?[0-5]?\d?)$/', $date, $matches)) {
if (strpos($date, '-') !== FALSE) {
$dateVal .= array_shift($matches);
}
+ if (!CRM_Utils_Rule::dateTime($dateVal)) {
+ return NULL;
+ }
+ $dateVal = CRM_Utils_Date::customFormat(preg_replace("/(:|\s)?/", '', $dateVal), '%Y%m%d%H%i%s');
+ return $dateVal;
}
}
// validate date.
- $valid = CRM_Utils_Rule::$ruleName($dateVal);
-
- if ($valid) {
- // format date and time to default.
- if ($ruleName == 'dateTime') {
- $dateVal = CRM_Utils_Date::customFormat(preg_replace("/(:|\s)?/", "", $dateVal), '%Y%m%d%H%i');
- // hack to add seconds
- $dateVal .= '00';
- }
- $formattedDate = $dateVal;
- }
+ return CRM_Utils_Rule::date($dateVal) ? $dateVal : NULL;
}
- return $formattedDate;
+ return NULL;
}
/**
return $dateObject->format($format);
}
+ /**
+ * Check if the value returned by a date picker has a date section (ie: includes
+ * a '-' character) if it includes a time section (ie: includes a ':').
+ *
+ * @param string $value
+ * A date/time string input from a datepicker value.
+ *
+ * @return bool
+ * TRUE if valid, FALSE if there is a time without a date.
+ */
+ public static function datePickerValueWithTimeHasDate($value) {
+ // If there's no : (time) or a : and a - (date) then return true
+ return (
+ strpos($value, ':') === FALSE
+ || strpos($value, ':') !== FALSE && strpos($value, '-') !== FALSE
+ );
+ }
+
+ /**
+ * Validate start and end dates entered on a form to make sure they are
+ * logical. Expects the form keys to be start_date and end_date.
+ *
+ * @param string $startFormKey
+ * The form element key of the 'start date'
+ * @param string $startValue
+ * The value of the 'start date'
+ * @param string $endFormKey
+ * The form element key of the 'end date'
+ * @param string $endValue
+ * The value of the 'end date'
+ *
+ * @return array|bool
+ * TRUE if valid, an array of the erroneous form key, and error message to
+ * use otherwise.
+ */
+ public static function validateStartEndDatepickerInputs($startFormKey, $startValue, $endFormKey, $endValue) {
+
+ // Check date as well as time is set
+ if (!empty($startValue) && !self::datePickerValueWithTimeHasDate($startValue)) {
+ return ['key' => $startFormKey, 'message' => ts('Please enter a date as well as a time.')];
+ }
+ if (!empty($endValue) && !self::datePickerValueWithTimeHasDate($endValue)) {
+ return ['key' => $endFormKey, 'message' => ts('Please enter a date as well as a time.')];
+ }
+
+ // Check end date is after start date
+ if (!empty($startValue) && !empty($endValue) && $endValue < $startValue) {
+ return ['key' => $endFormKey, 'message' => ts('The end date should be after the start date.')];
+ }
+
+ return TRUE;
+ }
+
}