note 88374 deleted from function.date by tularis
| From: | tularis@php.net | Date: | Thu, 09 Feb 2012 20:58:49 +0000 |
| Subject: | note 88374 deleted from function.date by tularis | ||
| References: | 1 | Groups: | php.notes |
| Request: | Send a blank email to php-notes+get-185995@lists.php.net to get a copy of this message | ||
Note Submitter: uramihsayibok, gmail, com
----
In a refreshing change, this code snippet is *not* about calculating date differences or anything
like that.
<background-story>
I've always preferred date() over strftime() because of what each offers. For example, date has
an st/nd/rd for the day number (S) while strftime does not. It also has an unpadded day number (j)
that strftime doesn't (%e pads it with a space).
On the other hand, each character in the format string for date() is translated unless you prepend a
backslash...
Recently I've wanted to create links with date information in it. Like with "January 21st
2009" each part would be a link (January => /2009/01, 21st => /2009/01/21, 2009 =>
/2009). date() makes this difficult because the HTML markup gets the treatment as well as the Y/m/d
characters. Escaping all of those is ugly, not to mention annoying.
</background-story>
Here's my combination of date's placeholders and strftime's % markers. It's the
best solution I could think of (at 5am mind you) but I'm open to suggestions.
Lots of comments because the code is rather tricky.
<?php
/**
* Combines placeholders from date() with the % marker from strftime()
*
* Like strftime, use %% for a literal %.
*
* @see date, strftime
* @param string $format The format of the outputted date string
* @param int $timestamp An integer Unix timestamp that defaults to the current local time
* @return A formatted date string
*/
function strfdate($format, $timestamp = null) {
// look for tokens
if (preg_match_all('/(?<!%)(%%)*%(.)/', $format, $matches)) {
// passing false or null as the timestamp doesn't work so we
// have to generate the default ourselves
if ($timestamp === null) $timestamp = time();
// run each token through date - all at once
// combines them into a "a!b!c!d" list, runs it through date,
// and splits it apart again
$parts = explode("!", date(implode("!", $matches[2]), $timestamp));
// (! should never show up in date() output so this works)
// a second function is used sequentially:
// the Xth time this function is called it will replace the Xth token
// with the corresponding element in $parts (which is passed through as $a)
//
// @param array $a Meant to be $parts as defined above
// @return $a[X] where X is how many times this function has been called
$replace = create_function('$a', 'static $i = 0; return $a[$i++];');
// find each token and get the replacement data from the $replace function
// note how the text being replaced isn't used anywhere: we already know
// what it is as it was used to create the $parts array
$result = preg_replace('/(%*)%./e', '"$1" . $replace($parts)',
$format);
// finally "unescape" any %s
$result = str_replace("%%", "%", $result);
return $result;
}
return $format;
}
?>