<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DZone Snippets: Charlie's Code Snippets</title>
    <link>http://snippets.dzone.com/posts</link>
    <pubDate>Fri, 25 Jul 2008 08:06:08 GMT</pubDate>
    <description>DZone Snippets: Charlie's Code Snippets</description>
    <item>
      <title>Determining the Number of Days in a Month with Javascript</title>
      <link>http://snippets.dzone.com/posts/show/2099</link>
      <description>Essentially, writing some code to determine the number of days in a given month of a given year with javascript is not the worlds most difficult task. It is the type of exercise that one would expect to be given as a newbie developer during a lab or lecture. The solution normally involves determining if the month is February, an month with 30 days or a month with 31 days, then (if February) checking if the year is a leap year. All these tests add up, however, and add several lines of code to your .js file. They are also unnecessary!&lt;br /&gt;&lt;br /&gt;Apparently, the javascript Date function allows you to overflow the day number parameter that you pass, creating a date in the next month. Deliberately overflowing the day parameter and checking how far the resulting date overlaps into the next month is a quick way to tell how many days there were in the queried month. Here is a function that does this:&lt;br /&gt;&lt;br /&gt;&lt;code&gt;&lt;br /&gt;function daysInMonth(iMonth, iYear)&lt;br /&gt;{&lt;br /&gt;	return 32 - new Date(iYear, iMonth, 32).getDate();&lt;br /&gt;}&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;N.B.: iMonth is zero based, so 0 represents January, 1 represents February, 2 represents March and 11 represents December. iYear is not zero based, this is the actual calendar year number. (2006 is actually 2006)&lt;br /&gt;&lt;br /&gt;Pray that the browser developers know the correct way to determine whether a year is a leap year! (It's more complicated than a simple mod 4 == 0) Here is a quote from Wikipedia's page on leap years: "The Gregorian calendar, the current standard calendar in most of the world, adds a 29th day to February in all years evenly divisible by 4, except for centennial years (those ending in '00'), which receive the extra day only if they are evenly divisible by 400. Thus 1600, 2000 and 2400 are leap years but 1700, 1800, 1900 and 2100 are not."&lt;br /&gt;&lt;br /&gt;To test this function, February in the years 2100, 2005, 2004, 2003, 2001, 2000 and 1999 should be checked. All of these should return 28, except for 2004 and 2000.&lt;br /&gt;&lt;br /&gt;&lt;code&gt;&lt;br /&gt;&lt;button onclick="alert(daysInMonth(1, 2100));"&gt;February 2100&lt;/button&gt;&lt;br /&gt;&lt;button onclick="alert(daysInMonth(1, 2005));"&gt;February 2005&lt;/button&gt;&lt;br /&gt;&lt;button onclick="alert(daysInMonth(1, 2004));"&gt;February 2004&lt;/button&gt;&lt;br /&gt;&lt;button onclick="alert(daysInMonth(1, 2003));"&gt;February 2003&lt;/button&gt;&lt;br /&gt;&lt;button onclick="alert(daysInMonth(1, 2001));"&gt;February 2001&lt;/button&gt;&lt;br /&gt;&lt;button onclick="alert(daysInMonth(1, 2000));"&gt;February 2000&lt;/button&gt;&lt;br /&gt;&lt;button onclick="alert(daysInMonth(1, 1999));"&gt;February 1999&lt;/button&gt;&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;How does this function work? It is quite simple. When the Date() function is given a day number that is greater than the number of days in the given month of the given year, it wraps the date into the next month. The getDate() function returns the day of the month, starting from the beginning of the month that the date is in. So, day 32 of March is considered to be day 1 of April. Subtracting 1 from 32 gives the correct number of days in March!</description>
      <pubDate>Thu, 25 May 2006 12:02:48 GMT</pubDate>
      <guid>http://snippets.dzone.com/posts/show/2099</guid>
      <author>Charlie (Stephen Martindale)</author>
    </item>
    <item>
      <title>MySql Backups Under Windows</title>
      <link>http://snippets.dzone.com/posts/show/1693</link>
      <description>This batch script will backup any MySql database on the local machine, including all routines (stored procedures and functions), to a file named after the database followed by the date (YYYY-MM-DD) and time (HHMMSSSS). The first argument is the database name, second is the username to run the backup as and third is the password.&lt;br /&gt;&lt;br /&gt;This script requires your date and time formats to be the windows default formats. Changing them can break this script. The script pauses at the end to cause a cmd window to remain open for long enough for the user to read the output.&lt;br /&gt;&lt;br /&gt;&lt;code&gt;&lt;br /&gt;@echo off&lt;br /&gt;echo Starting Backup of Database: %1&lt;br /&gt;&lt;br /&gt;For /f "tokens=2-4 delims=/ " %%a in ('date /t') do (set dt=%%c-%%a-%%b)&lt;br /&gt;For /f "tokens=1-4 delims=:." %%a in ('echo %time%') do (set tm=%%a%%b%%c%%d)&lt;br /&gt;set bkupfilename=%1 %dt% %tm%.bak&lt;br /&gt;echo Backing up to file: %bkupfilename%&lt;br /&gt;&lt;br /&gt;mysqldump %1 --routines -u %2 -p%3 &gt; "%bkupfilename%"&lt;br /&gt;&lt;br /&gt;echo Backup Complete!&lt;br /&gt;pause&lt;br /&gt;echo on&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;-- &lt;br /&gt;Version 0.1.0 - 2006-03-13&lt;br /&gt;STEM: The STEM Cells of PHP&lt;br /&gt;This work is licensed under a Creative Commons Attribution-ShareAlike 2.5 License&lt;br /&gt;http://creativecommons.org/licenses/by-sa/2.5/</description>
      <pubDate>Mon, 13 Mar 2006 17:29:02 GMT</pubDate>
      <guid>http://snippets.dzone.com/posts/show/1693</guid>
      <author>Charlie (Stephen Martindale)</author>
    </item>
    <item>
      <title>Space-Separated Tag Parser</title>
      <link>http://snippets.dzone.com/posts/show/1625</link>
      <description>Here is a function that accepts a string containing tags and returns an array of extracted tags. (Updated to ignore duplicates)&lt;br /&gt;&lt;code&gt;&lt;br /&gt;/**&lt;br /&gt; * Parses a String of Tags&lt;br /&gt; *&lt;br /&gt; * Tags are space delimited. Either single or double quotes mark a phrase.&lt;br /&gt; * Odd quotes will cause everything on their right to reflect as one single&lt;br /&gt; * tag or phrase. All white-space within a phrase is converted to single&lt;br /&gt; * space characters. Quotes burried within tags are ignored! Duplicate tags&lt;br /&gt; * are ignored, even duplicate phrases that are equivalent.&lt;br /&gt; *&lt;br /&gt; * Returns an array of tags.&lt;br /&gt; */&lt;br /&gt;function ParseTagString($sTagString)&lt;br /&gt;{&lt;br /&gt;	$arTags = array();		// Array of Output&lt;br /&gt;	$cPhraseQuote = null;	// Record of the quote that opened the current phrase&lt;br /&gt;	$sPhrase = null;		// Temp storage for the current phrase we are building&lt;br /&gt;	&lt;br /&gt;	// Define some constants&lt;br /&gt;	static $sTokens = " \r\n\t";	// Space, Return, Newline, Tab&lt;br /&gt;	static $sQuotes = "'\"";		// Single and Double Quotes&lt;br /&gt;	&lt;br /&gt;	// Start the State Machine&lt;br /&gt;	do&lt;br /&gt;	{&lt;br /&gt;		// Get the next token, which may be the first&lt;br /&gt;		$sToken = isset($sToken)? strtok($sTokens) : strtok($sTagString, $sTokens);&lt;br /&gt;		&lt;br /&gt;		// Are there more tokens?&lt;br /&gt;		if ($sToken === false)&lt;br /&gt;		{&lt;br /&gt;			// Ensure that the last phrase is marked as ended&lt;br /&gt;			$cPhraseQuote = null;&lt;br /&gt;		}&lt;br /&gt;		else&lt;br /&gt;		{		&lt;br /&gt;			// Are we within a phrase or not?&lt;br /&gt;			if ($cPhraseQuote !== null)&lt;br /&gt;			{&lt;br /&gt;				// Will the current token end the phrase?&lt;br /&gt;				if (substr($sToken, -1, 1) === $cPhraseQuote)&lt;br /&gt;				{&lt;br /&gt;					// Trim the last character and add to the current phrase, with a single leading space if necessary&lt;br /&gt;					if (strlen($sToken) &gt; 1) $sPhrase .= ((strlen($sPhrase) &gt; 0)? ' ' : null) . substr($sToken, 0, -1);&lt;br /&gt;					$cPhraseQuote = null;&lt;br /&gt;				}&lt;br /&gt;				else&lt;br /&gt;				{&lt;br /&gt;					// If not, add the token to the phrase, with a single leading space if necessary&lt;br /&gt;					$sPhrase .= ((strlen($sPhrase) &gt; 0)? ' ' : null) . $sToken;&lt;br /&gt;				}&lt;br /&gt;			}&lt;br /&gt;			else&lt;br /&gt;			{&lt;br /&gt;				// Will the current token start a phrase?&lt;br /&gt;				if (strpos($sQuotes, $sToken[0]) !== false)&lt;br /&gt;				{&lt;br /&gt;					// Will the current token end the phrase?&lt;br /&gt;					if ((strlen($sToken) &gt; 1) &amp;&amp; ($sToken[0] === substr($sToken, -1, 1)))&lt;br /&gt;					{&lt;br /&gt;						// The current token begins AND ends the phrase, trim the quotes&lt;br /&gt;						$sPhrase = substr($sToken, 1, -1);&lt;br /&gt;					}&lt;br /&gt;					else&lt;br /&gt;					{&lt;br /&gt;						// Remove the leading quote&lt;br /&gt;						$sPhrase = substr($sToken, 1);&lt;br /&gt;						$cPhraseQuote = $sToken[0];&lt;br /&gt;					}&lt;br /&gt;				}&lt;br /&gt;				else&lt;br /&gt;					$sPhrase = $sToken;&lt;br /&gt;			}&lt;br /&gt;		}&lt;br /&gt;		&lt;br /&gt;		// If, at this point, we are not within a phrase, the prepared phrase is complete and can be added to the array&lt;br /&gt;		if (($cPhraseQuote === null) &amp;&amp; ($sPhrase != null))&lt;br /&gt;		{&lt;br /&gt;			$sPhrase = strtolower($sPhrase);&lt;br /&gt;			if (!in_array($sPhrase, $arTags)) $arTags[] = $sPhrase;&lt;br /&gt;			$sPhrase = null;&lt;br /&gt;		}&lt;br /&gt;	}&lt;br /&gt;	while ($sToken !== false);	// Stop when we receive FALSE from strtok()&lt;br /&gt;	return $arTags;&lt;br /&gt;}&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;The string can be recreated from the array with the use of this reverse function:&lt;br /&gt;&lt;code&gt;&lt;br /&gt;/**&lt;br /&gt; * Reverses ParseTagString()&lt;br /&gt; */&lt;br /&gt;function CreateTagString($arTags)&lt;br /&gt;{&lt;br /&gt;	// Prepare each tag to be imploded&lt;br /&gt;	for ($i = 0; $i &lt; sizeof($arTags); $i++)&lt;br /&gt;	{&lt;br /&gt;		// Record findings&lt;br /&gt;		$bContainsWhitespace = false;	// Was whitespace found?&lt;br /&gt;		$cRequiredQuote = '"';			// Use double-quote by default&lt;br /&gt;		$cLastChar = null;&lt;br /&gt;	&lt;br /&gt;		// Search the tag&lt;br /&gt;		for ($j = 0; $j &lt; strlen($arTags[$i]); $j++)&lt;br /&gt;		{&lt;br /&gt;			$c = $arTags[$i][$j];&lt;br /&gt;			&lt;br /&gt;			// If the current character is a space&lt;br /&gt;			if ($c === ' ')&lt;br /&gt;			{&lt;br /&gt;				$bContainsWhitespace = true;&lt;br /&gt;				&lt;br /&gt;				// If the previous char was a double quote, we require single quotes round our phrase&lt;br /&gt;				if ($cLastChar === '"')&lt;br /&gt;				{&lt;br /&gt;					$cRequiredQuote = "'";&lt;br /&gt;					break;	// There is no more point in continuing our search, we cant handle double-mixed quotes&lt;br /&gt;				}&lt;br /&gt;			}&lt;br /&gt;			&lt;br /&gt;			// Record this char as the last char&lt;br /&gt;			$cLastChar = $c;&lt;br /&gt;		}&lt;br /&gt;		&lt;br /&gt;		// Quote if necessary&lt;br /&gt;		if ($bContainsWhitespace) $arTags[$i] = $cRequiredQuote . $arTags[$i] . $cRequiredQuote;&lt;br /&gt;	}&lt;br /&gt;	return implode(' ', $arTags);&lt;br /&gt;}&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;To test the whole system, use the following array of test cases:&lt;br /&gt;&lt;code&gt;&lt;br /&gt;$arTestInputs = array(&lt;br /&gt;	"this test ensures that words are correctly split",&lt;br /&gt;	"in this test \"phrases\" and \"multi-word phrases\" are tested",&lt;br /&gt;	"this test shows the behaviour if an \"odd quote is detected",&lt;br /&gt;	"this test shows that 'different quotes' work too",&lt;br /&gt;	"but mixed quotes fail: \"test phrase' does not stop on the quote",&lt;br /&gt;	"which can be usefull in some cases where \"the systems' requirements\" state that it is necessary",&lt;br /&gt;	"quotes need not be attached to \" their phrase \"",&lt;br /&gt;	"embedded\"quotes are ignored!",&lt;br /&gt;	"this is also usefull and demonstrates the system's coolness",&lt;br /&gt;	"redundant   white-space is   removed from \"  tags    and phrases\"",&lt;br /&gt;	"\"\"double quotes\"\" will result in single quotes!",&lt;br /&gt;	"remember that 'double-quotes\" may be nested within single quotes'",&lt;br /&gt;	"TaGs ArE NOT case SENsITiVE!",&lt;br /&gt;	"a duplicate tag will be removed from the tag list",&lt;br /&gt;	"even a \" complex phrase\" that is equivalent to another 'compleX   PHrASe   '"&lt;br /&gt;);&lt;br /&gt;&lt;br /&gt;foreach ($arTestInputs as $sTest)&lt;br /&gt;{&lt;br /&gt;	print ("&lt;pre&gt;$sTest&lt;/pre&gt;");&lt;br /&gt;	print "&lt;pre&gt;";&lt;br /&gt;	print_r (ParseTagString($sTest));&lt;br /&gt;	print "&lt;/pre&gt;";&lt;br /&gt;	print "&lt;pre&gt;";&lt;br /&gt;	print CreateTagString(ParseTagString($sTest));&lt;br /&gt;	print "&lt;/pre&gt;";&lt;br /&gt;	print "&lt;hr /&gt;";&lt;br /&gt;}&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;2006-03-09 0.1.0 - 0.2.0 Duplicate phrases are now ignored.&lt;br /&gt;&lt;br /&gt;-- &lt;br /&gt;Version 0.2.0 - 2006-03-09&lt;br /&gt;STEM: The STEM Cells of PHP&lt;br /&gt;This work is licensed under a Creative Commons Attribution-ShareAlike 2.5 License&lt;br /&gt;http://creativecommons.org/licenses/by-sa/2.5/</description>
      <pubDate>Fri, 03 Mar 2006 16:58:01 GMT</pubDate>
      <guid>http://snippets.dzone.com/posts/show/1625</guid>
      <author>Charlie (Stephen Martindale)</author>
    </item>
    <item>
      <title>Converting old PHP Errors into Exceptions</title>
      <link>http://snippets.dzone.com/posts/show/1617</link>
      <description>The PHP5 Exception class will not work correctly. It would reflect an incorrect line number and file name and not record the 'errcontext' value associated with PHP errors. To solve this problem, we must extend the Exception class.&lt;br /&gt;&lt;code&gt;&lt;br /&gt;/**&lt;br /&gt; * This exception behaves like a "old school" PHP Error&lt;br /&gt; */&lt;br /&gt;class STEM_ErrorException extends Exception&lt;br /&gt;{&lt;br /&gt;	/**&lt;br /&gt;	 * The PHP Error Context&lt;br /&gt;	 *&lt;br /&gt;	 * The fifth parameter is optional, errcontext, which is an array that points to the active symbol table at the point the error occurred. In other words, errcontext  will contain an array of every variable that existed in the scope the error was triggered in. User error handler must not modify error context.&lt;br /&gt;	 */&lt;br /&gt;	private $m_arContext;&lt;br /&gt;&lt;br /&gt;	/**&lt;br /&gt;	 * Constructor&lt;br /&gt;	 */&lt;br /&gt;	public function __construct($vMessage, $vCode, $vFile, $vLine, $arContext = null)&lt;br /&gt;	{&lt;br /&gt;		parent::__construct($vMessage, $vCode);&lt;br /&gt;		&lt;br /&gt;		$this-&gt;file = $vFile;&lt;br /&gt;		$this-&gt;line = $vLine;&lt;br /&gt;		&lt;br /&gt;		$this-&gt;m_arContext = $arContext;&lt;br /&gt;	}&lt;br /&gt;}&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;We need to define a function to handle errors. We also want to write two helper functions that will set and restore the error handler to our function. To do this, we write three methods in an abstract class.&lt;br /&gt;&lt;code&gt;&lt;br /&gt;/**&lt;br /&gt; * STEM Error Handler&lt;br /&gt; *&lt;br /&gt; * Registers Itself as a PHP Error Handler and proceeds to convert all&lt;br /&gt; * native "old school" PHP errors into new PHP5 Exceptions.&lt;br /&gt; *&lt;br /&gt; * Call STEM_ErrorHandler::Initialize(); before your try blocks and&lt;br /&gt; * STEM_ErrorHandler::Uninitialize(); afterwards.&lt;br /&gt; */&lt;br /&gt;abstract class STEM_ErrorHandler&lt;br /&gt;{&lt;br /&gt;	/**&lt;br /&gt;	 * Encapsulates set_error_handler()&lt;br /&gt;	 */&lt;br /&gt;	public static function Initialize()&lt;br /&gt;	{&lt;br /&gt;		set_error_handler(array("STEM_ErrorHandler", "HandleError"));&lt;br /&gt;	}&lt;br /&gt;	&lt;br /&gt;	/**&lt;br /&gt;	 * Encapsulates restore_error_handler()&lt;br /&gt;	 */&lt;br /&gt;	public static function Uninitialize()&lt;br /&gt;	{&lt;br /&gt;		restore_error_handler();&lt;br /&gt;	}&lt;br /&gt;	&lt;br /&gt;	/**&lt;br /&gt;	 * Handles PHP Errors&lt;br /&gt;	 */&lt;br /&gt;	public static function HandleError($errno, $errstr, $errfile, $errline, $errcontext)&lt;br /&gt;	{&lt;br /&gt;		throw new STEM_ErrorException($errstr, $errno, $errfile, $errline, $errcontext);&lt;br /&gt;	}&lt;br /&gt;}&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;To test it, we create a file that triggers errors. Before triggering the first error, we call Initialize(). We then Uninitialize() the error handler and trigger the error again to check that our error handler has been removed. It is important to check the line numbers mentioned in the message that this prints!&lt;br /&gt;&lt;code&gt;&lt;br /&gt;STEM_ErrorHandler::Initialize();&lt;br /&gt;&lt;br /&gt;try&lt;br /&gt;{&lt;br /&gt;	trigger_error("Hello World!");&lt;br /&gt;}&lt;br /&gt;catch (Exception $e)&lt;br /&gt;{&lt;br /&gt;	print $e;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;STEM_ErrorHandler::Uninitialize();&lt;br /&gt;print "&lt;hr /&gt;";&lt;br /&gt;&lt;br /&gt;try&lt;br /&gt;{&lt;br /&gt;	trigger_error("Hello World!");&lt;br /&gt;}&lt;br /&gt;catch (Exception $e)&lt;br /&gt;{&lt;br /&gt;	print $e;&lt;br /&gt;}&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;-- &lt;br /&gt;Version 0.1.0 - 2006-02-14&lt;br /&gt;STEM: The STEM Cells of PHP&lt;br /&gt;This work is licensed under a Creative Commons Attribution-ShareAlike 2.5 License&lt;br /&gt;http://creativecommons.org/licenses/by-sa/2.5/</description>
      <pubDate>Thu, 02 Mar 2006 18:57:31 GMT</pubDate>
      <guid>http://snippets.dzone.com/posts/show/1617</guid>
      <author>Charlie (Stephen Martindale)</author>
    </item>
    <item>
      <title>Random Password Generator</title>
      <link>http://snippets.dzone.com/posts/show/1487</link>
      <description>This is a complete, working, random password generator for PHP. It allows the implementor to customize the character sets that the password is generated from.&lt;br /&gt;&lt;br /&gt;To configure the generator, create the following configuration array. It is an array of arrays where each element array defines the characters in the pool and the minimum and maximum number of these characters that must appear in the result password. Each member array is given a single character token that identifies it.&lt;br /&gt;&lt;code&gt;&lt;br /&gt;// Configuration definitions, move to config.php&lt;br /&gt;$CONFIG['security']['password_generator'] = array(&lt;br /&gt;	"C" =&gt; array('characters' =&gt; 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ', 'minimum' =&gt; 4, 'maximum' =&gt; 6),&lt;br /&gt;	"S" =&gt; array('characters' =&gt; "!@()-_=+?*^&amp;", 'minimum' =&gt; 1, 'maximum' =&gt; 2),&lt;br /&gt;	"N" =&gt; array('characters' =&gt; '1234567890', 'minimum' =&gt; 2, 'maximum' =&gt; 2)&lt;br /&gt;);&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;The GeneratePassword() function uses the configuration array to generate a password. It starts by creating a meta-password, which is a shuffled string of the tokens from the configuration data. After the meta-password is ready, it loops through it and uses each token to choose a character from the pool of available characters defined in the configuration arrays. Once it is done, it returns the result.&lt;br /&gt;&lt;code&gt;&lt;br /&gt;function STEM_GeneratePassword()&lt;br /&gt;{&lt;br /&gt;	// Create the meta-password&lt;br /&gt;	$sMetaPassword = "";&lt;br /&gt;	&lt;br /&gt;	global $CONFIG;&lt;br /&gt;	$ahPasswordGenerator = $CONFIG['security']['password_generator'];&lt;br /&gt;	foreach ($ahPasswordGenerator as $cToken =&gt; $ahPasswordSeed)&lt;br /&gt;		$sMetaPassword .= str_repeat($cToken, rand($ahPasswordSeed['minimum'], $ahPasswordSeed['maximum']));&lt;br /&gt;		&lt;br /&gt;	$sMetaPassword = str_shuffle($sMetaPassword);&lt;br /&gt;	&lt;br /&gt;	// Create the real password&lt;br /&gt;	$arBuffer = array();&lt;br /&gt;	for ($i = 0; $i &lt; strlen($sMetaPassword); $i ++)&lt;br /&gt;		$arBuffer[] = $ahPasswordGenerator[(string)$sMetaPassword[$i]]['characters'][rand(0, strlen($ahPasswordGenerator[$sMetaPassword[$i]]['characters']) - 1)];&lt;br /&gt;&lt;br /&gt;	return implode("", $arBuffer);&lt;br /&gt;}&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;-- &lt;br /&gt;Version 0.1.0 - 2006-02-14&lt;br /&gt;STEM: The STEM Cells of PHP&lt;br /&gt;This work is licensed under a Creative Commons Attribution-ShareAlike 2.5 License&lt;br /&gt;http://creativecommons.org/licenses/by-sa/2.5/</description>
      <pubDate>Tue, 14 Feb 2006 23:50:17 GMT</pubDate>
      <guid>http://snippets.dzone.com/posts/show/1487</guid>
      <author>Charlie (Stephen Martindale)</author>
    </item>
    <item>
      <title>DateTime with PHP and MySql</title>
      <link>http://snippets.dzone.com/posts/show/1455</link>
      <description>This script shows, by example, how to convert from a UNIX Timestamp (the returned data type from the PHP time() or mktime() functions) into a string that can be stored in MySql's DATETIME or TIMESTAMP fields. It also shows how to convert back into a UNIX Timestamp. The times are stored in the database as GMT/UTC times, so finally, it shows how to convert from the resulting UNIX timestamp into a string that represents the time with a given GMT/UTC offset.&lt;br /&gt;&lt;br /&gt;Create the UNIX Timestamp, using the current system time.&lt;br /&gt;&lt;code&gt;&lt;br /&gt;// Create the UNIX Timestamp, using the current system time&lt;br /&gt;$tUnixTime = time();&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;Convert that UNIX Timestamp into a string, safe for MySql. The string will be in the format CCYY-MM-DD HH:MM:SS and will represent the GMT/UTC time represented by the UNIX Timestamp. Example: 2006-02-10 20:33:55&lt;br /&gt;&lt;code&gt;&lt;br /&gt;// Convert that UNIX Timestamp into a string (GMT), safe for MySql&lt;br /&gt;$sGMTMySqlString = gmdate("Y-m-d H:i:s", $tUnixTime);&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;The string created above is suitable for sending to MySql and storing in a DATETIME or TIMESTAMP field. This snippet does not include the code that would store and retrieve the data.&lt;br /&gt;&lt;br /&gt;Parse the String and store the result in a new UNIX Timestamp. Because strtotime() thinks that any string passed to it, that does not specify a timezone, is in the local timezone, according to the settings in your configuration, we append " GMT" to the string that is returned from MySql. This creates a new string that is both compliant with strtotime() and explicitly a GMT value.&lt;br /&gt;&lt;code&gt;&lt;br /&gt;// Parse the String into a new UNIX Timestamp&lt;br /&gt;$tParsedTime = strtotime($sGMTMySqlString . " GMT");&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;Show the two values, in W3C format, for debugging. W3C format dates include the full date, time and timezone information. If we visually or programmatically compare the two values, they should be identical in all aspects.&lt;br /&gt;&lt;code&gt;&lt;br /&gt;// Show the Original Time and Parsed Time on the screen, in W3C Format&lt;br /&gt;print "Original Time: " . date(DATE_W3C, $tUnixTime);&lt;br /&gt;print "Parsed Time: " . date(DATE_W3C, $tParsedTime);&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;The following two lines demonstrate how to take one of these UNIX timestamps and convert it into a user-friendly string, using a time offset. Typically, you would store this time offset in your user's profile.&lt;br /&gt;&lt;code&gt;&lt;br /&gt;// Create a String showing the DateTime in CCYY-MM-DD Format in a Specified Zone&lt;br /&gt;$fUTCOffset = +2.00; // GMT/UTC Offset in Hours (2.50 = 2 hours 30 minutes)&lt;br /&gt;print "Time in GMT+2: " . gmdate("Y-m-d H:i:s", $tUnixTime + $fUTCOffset * 3600);&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;I am not sure whether my idea to use a floating point number to represent the user's time zone is correct. I must check the standard. If the standard is to use a time-span value (2.50 is not 2 hours 30 minutes but 2 hours and 50 minutes, 2.30 is 2 hours and 30 minutes) I will change it. This is a minor change.&lt;br /&gt;&lt;br /&gt;I did not know of a PHP function that would convert a GMT/UTC UNIX Timestamp into a string representing a time in a specified zone. All I could find is the date() function which uses the current zone according to the config and the gmdate() zone which returns GMT/UTC. To implement the functionality, I modified the date by adding to it and then converting to GMT/UTC. I do not like this, but it works.&lt;br /&gt;&lt;br /&gt;This code makes no attempt to guess whether the current user is affected by DST or not. It simply uses an offset from GMT/UTC. According to my research, DST guessing is dodgy at best and, according to some, soon to be outdated by a change to the DST system in America.&lt;br /&gt;&lt;br /&gt;I am not sure, even if I knew how, that I would trust built-in time zone functionality. I would suspect its accuracy for the same reasons I don't use automatic guessing of DST status.&lt;br /&gt;&lt;br /&gt;-- &lt;br /&gt;Version 0.0.1 - 2006-02-10&lt;br /&gt;Stephen's Modules: DateTime with PHP and MySql&lt;br /&gt;This work is licensed under a Creative Commons Attribution-ShareAlike 2.5 License&lt;br /&gt;http://creativecommons.org/licenses/by-sa/2.5/</description>
      <pubDate>Sat, 11 Feb 2006 01:10:18 GMT</pubDate>
      <guid>http://snippets.dzone.com/posts/show/1455</guid>
      <author>Charlie (Stephen Martindale)</author>
    </item>
  </channel>
</rss>
