public static function strToDate($string) { // Parse 'yesterday'/'today'/'tomorrow' $lc = strtolower($string); if ($lc == 'yesterday' || $lc == self::getString('date.yesterday')) { $string = date("Y-m-d", strtotime('yesterday')); } else { if ($lc == 'today' || $lc == self::getString('date.today')) { $string = date("Y-m-d"); } else { if ($lc == 'tomorrow' || $lc == self::getString('date.tomorrow')) { $string = date("Y-m-d", strtotime('tomorrow')); } } } $date = array(); // skip empty things if (!$string) { return $date; } $string = preg_replace(array("/^\\s+/", "/\\s+\$/", "/\\s+/"), array("", "", " "), $string); // first, directly inspect the string preg_match(self::$slashRE, $string, $m); if ($m && (empty($m[5]) || $m[3] == $m[5] || $m[3] == "年" && $m[5] == "月") && (!empty($m[2]) && !empty($m[4]) && !empty($m[6]) || empty($m[1]) && empty($m[7]))) { // require that either all parts are found, // or else this is the entire date field // figure out date based on parts if (mb_strlen($m[2]) == 3 || mb_strlen($m[2]) == 4 || $m[3] == "年") { // ISO 8601 style date (big endian) $date['year'] = $m[2]; $date['month'] = $m[4]; $date['day'] = $m[6]; } else { // local style date (middle or little endian) $date['year'] = $m[6]; $country = substr(self::$locale, 3); if ($country == "US" || $country == "FM" || $country == "PW" || $country == "PH") { // The Philippines $date['month'] = $m[2]; $date['day'] = $m[4]; } else { $date['month'] = $m[4]; $date['day'] = $m[2]; } } if ($date['year']) { $date['year'] = (int) $date['year']; } if ($date['day']) { $date['day'] = (int) $date['day']; } if ($date['month']) { $date['month'] = (int) $date['month']; if ($date['month'] > 12) { // swap day and month $tmp = $date['day']; $date['day'] = $date['month']; $date['month'] = $tmp; } } if ((empty($date['month']) || $date['month'] <= 12) && (empty($date['day']) || $date['day'] <= 31)) { if (!empty($date['year']) && $date['year'] < 100) { // for two digit years, determine proper $year = date('Y'); $twoDigitYear = date('y'); $century = $year - $twoDigitYear; if ($date['year'] <= $twoDigitYear) { // assume this date is from our century $date['year'] = $century + $date['year']; } else { // assume this date is from the previous century $date['year'] = $century - 100 + $date['year']; } } Z_Core::debug("DATE: retrieved with algorithms: " . json_encode($date)); $date['part'] = $m[1] . $m[7]; } else { // give up; we failed the sanity check Z_Core::debug("DATE: algorithms failed sanity check"); $date = array("part" => $string); } } else { //Zotero.debug("DATE: could not apply algorithms"); $date['part'] = $string; } // couldn't find something with the algorithms; use regexp // YEAR if (empty($date['year'])) { if (preg_match(self::$yearRE, $date['part'], $m)) { $date['year'] = $m[2]; $date['part'] = $m[1] . $m[3]; Z_Core::debug("DATE: got year (" . $date['year'] . ", " . $date['part'] . ")"); } } // MONTH if (empty($date['month'])) { // compile month regular expression $months = array('Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'); // If using a non-English bibliography locale, try those too if (self::$locale != 'en-US') { throw new Exception("Unimplemented"); //$months = array_merge($months, .concat(Zotero.$date['month']s.short); } if (!self::$monthRE) { self::$monthRE = "/^(.*)\\b(" . implode("|", $months) . ")[^ ]*(?: (.*)\$|\$)/iu"; } if (preg_match(self::$monthRE, $date['part'], $m)) { // Modulo 12 in case we have multiple languages $date['month'] = array_search(ucwords(strtolower($m[2])), $months) % 12 + 1; $date['part'] = $m[1] . (isset($m[3]) ? $m[3] : ''); Z_Core::debug("DATE: got month (" . $date['month'] . ", " . $date['part'] . ")"); } } // DAY if (empty($date['day'])) { // compile day regular expression if (!self::$dayRE) { $daySuffixes = preg_replace("/, ?/", "|", self::getString("date.daySuffixes")); self::$dayRE = "/\\b([0-9]{1,2})(?:" . $daySuffixes . ")?\\b(.*)/iu"; } if (preg_match(self::$dayRE, $date['part'], $m, PREG_OFFSET_CAPTURE)) { $day = (int) $m[1][0]; // Sanity check if ($day <= 31) { $date['day'] = $day; if ($m[0][1] > 0) { $date['part'] = substr($date['part'], 0, $m[0][1]); if ($m[2][0]) { $date['part'] .= " " . $m[2][0]; } } else { $date['part'] = $m[2][0]; } Z_Core::debug("DATE: got day (" . $date['day'] . ", " . $date['part'] . ")"); } } } // clean up date part if ($date['part']) { $date['part'] = preg_replace(array("/^[^A-Za-z0-9]+/", "/[^A-Za-z0-9]+\$/"), "", $date['part']); } if ($date['part'] === "" || !isset($date['part'])) { unset($date['part']); } return $date; }