Archive for November, 2008

Easily calculate dates and times in different timezones

Building off my last post, where I showed you how to easily display any public Twitter feed on your site, I ran into another problem: the dates that are delivered by the Twitter API all reflect Greenwich Mean Time (GMT). Now I thought about going the old route and doing some convoluted math using date(), strtotime(), and mktime(), but I thought it was time find a serious solution, one that would allow me to display the correct time for whatever timezone I wished.

So while searching the web, I came across an insightful post that discussed PHP’s built-in DateTime object. I try hard to keep up with all the tech in my job, but this one got through the cracks, and I was instantly intrigued. So after some research and fiddling, I came up with the following block of code, which will allow you to easily translate dates/times to and from any timezone.

date_default_timezone_set('GMT');
$datetime = new DateTime('2008-11-25 16:48:13');
$tz = new DateTimeZone('America/New_York');
$datetime->setTimezone($tz);
$time_display = $datetime->format('D, M jS g:ia T');

The process is a little convoluted, so here’s what’s going on. First we must set the system-wide timezone to match that of the date/time we would like to translate. In this example, it’s about 4:50pm on Nov 25, 2008 in the GMT timezone. Next we create a DateTime object with that time (FYI you can use any format accepted by strtotime()).

Next we create a DateTimeZone object. Keep in mind that this step stands completely on its own, and can be performed anytime up to now.

Finally, we pass the DateTimeZone object as the lone argument in a call to the setTimezone() method. This will change the timezone stored in $datetime from GMT to EST, and automatically update the date/time accordingly, which we output with a call to the format method.

Note that I used object-oriented syntax for this process, but there is a procedural style (i.e. functions) as well. I prefer OOP here because it’s just easier to read and follow.

Valid arguments for date_default_timezone_set() and DateTimeZone() come from PHP’s list of supported timezones.

So now that we can translate timezones, let’s apply it to my Twitter example…

<ul>
<?php
  if ( $twitter_xml = twitter_status('12345678') ) {
    date_default_timezone_set('GMT');
    $tz = new DateTimeZone('America/New_York');
    $i = 0;
    foreach ($twitter_xml->status as $key => $status) {
      $datetime = new DateTime($status->created_at);
      $datetime->setTimezone($tz);
      $time_display = $datetime->format('D, M jS g:ia T');
?>
  <li><?php echo $status->text . '<br />' . $time_display; ?></li>
<?php
      ++$i;
      if ($i == 5) break;
    }
?>
  <li><a href="http://twitter.com/YOUR_PROFILE_HERE">more...</a></li>
<?php
  } else {
    echo 'Sorry, Twitter seems to be unavailable at the moment...again...';
  }
?>
</ul>

Sidenote: While I was working on this I found GMT and UTC used almost interchangeably. For all intents and purposes, they are identical. But there is a technical difference: GMT is based on the rotation of the earth (less precise), while UTC is based on an atomic clock (more precise). Don’t worry, you and I are not the only ones who got confused.

Build a slick Twitter feed on your site

  1. Display Twitter updates on your website
  2. Calculate dates and times in different timezones (translate Twitter timestamps)
  3. Parse URL’s in text, create links


Display Twitter updates on your website

Update: I’ve added a new chunk of code that will download and store your Twitter posts in a database, allowing you to do whatever the heck you want with them. After you’ve finished reading this, be sure to check that out as well.

I am not a fan of social networking or so-called lifestreaming. I think it’s a BS excuse to fiddle on your computer more. Instead of telling everyone where you are and what you’re doing, go out and meet some friends for a drink.

However I did find a practical use for Twitter in a recent issue of php|architect (Twitter as a Development Tool by Sam McCallum). The article discussed using Twitter as an automated logger, where a program would make posts to a Twitter account based on system actions (i.e. log in/out, create accounts, etc.).

I decided to turn the idea around a bit and use Twitter as an activity log to chronicle my development work on a new project. Think SVN log comments without the repository. The site itself is currently a simple placeholder page, so Twitter updates make an easy way to keep a website fresh while building out the service that will eventually reside there. It also engages the users that wind up looking at the site, letting them know that it might be something of interest to them. That’s to say nothing of any SEO or attention-grabbing effects that may result from having a Twitter stream.

Given the rabidity surrounding said scoial networking silliness, I thought that finding a suitable plug ‘n play solution to this would be easy. Surprisingly (or perhaps unsurprisingly) many of the Twitter scripts I found were plain garbage. The following code was put together by sifting through what I found and putting the best working bits together. So if this sounds interesting, or if you were also frustrated with the plethora of crappy Twitter code, here’s how you can easily display your Twitter updates on any site using PHP.

First, grab this function…

function twitter_status($twitter_id, $hyperlinks = true) {
  $c = curl_init();
  curl_setopt($c, CURLOPT_URL, "http://twitter.com/statuses/user_timeline/$twitter_id.xml");
  curl_setopt($c, CURLOPT_RETURNTRANSFER, 1);
  curl_setopt($c, CURLOPT_CONNECTTIMEOUT, 3);
  curl_setopt($c, CURLOPT_TIMEOUT, 5);
  $response = curl_exec($c);
  $responseInfo = curl_getinfo($c);
  curl_close($c);
  if (intval($responseInfo['http_code']) == 200) {
    if (class_exists('SimpleXMLElement')) {
      $xml = new SimpleXMLElement($response);
      return $xml;
    } else {
      return $response;
    }
  } else {
    return false;
  }
}

I’m not going to discuss the various cURL options here or how Twitter uses cURL, as its outside the scope of our discussion here. If you’re lost or curious, you can read up on the cURL library, cURL in PHP, and/or the Twitter API.

As its name implies, twitter_status() will connect to Twitter and grab the timeline for the Twitter account identified by the $twitter_id. The $twitter_id is a unique number assigned to every Twitter account. You can find yours by visiting your profile page and examining the RSS link at the bottom left of the page. The URL will look like this:

http://twitter.com/statuses/user_timeline/12345678.rss

That 8-digit number at the end is your ID. Grab it and pass it as the lone argument to twitter_status(). Note that, as long as your Twitter profile is public, you do not need to pass any credentials to retrieve a user timeline. The API makes this information available to anyone, anywhere. There are more options that can be accessed through the user_timeline() function, if you’re curious.

The next step is to actually use the returned data, which comes in one of two forms: a SimpleXML object, or a raw XML document. SimpleXML is preferred because it’s a PHP object, and allows you access to all the usual object manipulation. Very easy. SimpleXML was added to PHP starting with version 5. The PHP manual has all the necessary details on SimpleXML.

The following code example assumes you’re using SimpleXML. Here I am taking the first five results and putting them in an HTML list. I’ll include a link to view the profile, as well as an error message in case Twitter is suffering from one of its famous fail-whale spasms.

<ul>
<?php
if ($twitter_xml = twitter_status('12345678')) {
  foreach ($twitter_xml->status as $key => $status) {
?>
  <li><?php echo $status->text; ?></li>
<?php
    ++$i;
    if ($i == 5) break;
  }
?>
  <li><a href="http://twitter.com/YOUR_PROFILE_HERE">more...</a></li>
<?php
} else {
  echo 'Sorry, Twitter seems to be unavailable at the moment...again...';
}
?>
</ul>

If you want to see this code in action, just check out the front page of Fwd:Vault, my new full-time startup. While you’re checking out the code in action, why don’t you follow along with me @fwdvault?

Build a slick Twitter feed on your site

  1. Display Twitter updates on your website
  2. Calculate dates and times in different timezones (translate Twitter timestamps)
  3. Parse URL’s in text, create links
  4. New Download and store Twitter posts in a MySQL table


There are only two types of coders

Across every language, platform, and experience level, you can summarize all programmers into just two groups:

Those who are constantly learning, and those who think they know everything.

The ones who learn are aware that they don’t know everything, and never hesitate to seek out new information when a new problem (or language, or platform) presents itself. They aren’t afraid to ask questions because asking is precisely what got them to their current level, and asking will propel them forward to greater levels of achievement.

The ones who think they know everything never do, because (a) knowledge is infinite, and (b) programming knowledge is infinity-squared. This field just grows and changes at way too fast a pace; anyone passing themselves off as a go-to resource has obviously stopped learning, and thus is automatically behind.

Thankfully, I think the vast majority of us land in the eager learner group. So when you do run across the rare know-it-all, do not hesitate to run the other way; you won’t have to go very far to find more like-minded colleagues.


Get number of message parts in an email using PHP

Alright, I admit up front that this is a pretty specific problem, but hopefully some Googlers will find it useful.

I recently had need for a small side project to read e-mails. Every e-mail is split up into parts; each “part” represents every separate piece of the e-mail. The plain text format, rich text or HTML formats, and attachments are all sent as parts. Problem is that there is no obvious way to quickly decipher just how many parts you have in a message. The documentation for the imap functions in PHP is also woefully inadequate. Maybe I’ll help flesh it out once this project is done.

Anyway, you can ascertain the total number of parts using the results from the function imap_fetchstructure(). The parts array in the returned object contains ALL the parts of the message, including the top level used to construct the rest of the object’s data. So, this simple call is all you need…

$structure = imap_fetchstructure($mbox, $message_num);
$total_parts = sizeof($structure->parts);


Why include_once and require_once may make you a crappy coder

Over the last few years, I’ve noticed that the PHP community has, in general, started to favor include_once() and require_once() over the more standard include() and require(). For the uninitiated, the “_once” version of each function will check to see if a file has already been loaded. If it has, it will safely bypass loading the file again without throwing an error, and continue parsing you code. For the really uninitiated, here’s the difference between require() and include() straight from the manual:

require() and include() are identical in every way except how they handle failure. They both produce a Warning, but require() results in a Fatal Error. In other words, don’t hesitate to use require() if you want a missing file to halt processing of the page. include() does not behave this way, the script will continue regardless. Be sure to have an appropriate include_path setting as well.

At first glance, this looks great! Since most files are only ever parsed once—did you know that it is legal to load the same file repeatedly?—these functions will save you from screwing up your code. No more worrying about reloaded files, repeating actions that cause aberrant behavior or flat out fatal errors.

Obviously the dynamic coding newbie uses these functions as training wheels. “I may have loaded, but I’m gonna load it again, just in case.” That’s understandable, and all well-and-good. If this is you, don’t make it a habit, learn to structure your code properly so that files that should be loaded once only ever have one opportunity to do so.

At the opposite end of spectrum, there are big-time PHP projects that prefer the _once versions exclusively. My own beloved Zen Cart has slowly been making the switch (new major revisions on the horizon do it more sweepingly). The CakePHP Coding Standards actually demand the use require_once():

When including files with classes or libraries, use only and always the require_once function.

Here the rationale is completely different, and completely informed. Because these projects are designed to allow extensive 3rd part manipulation, the chances for a file collision are fairly high. Think about situations where two different mods require the presence of a third “standard” mod library. They trade off a fair amount of performance to offer this flexibility, but at least they know what they’re doing.

If you’ve read this far, chances are you are not a newbie, but you sure as hell aren’t Zen Cart or CakePHP either. So, what business do you have using include_once() or require_once()? None, truth be told. And if you use them extensively, then the title of this article was written for you. Congrats!

The problem that these functions introduce for most developers is two-fold. First, there’s a performance penalty for using these functions, because the function must first check to see if a file has been loaded. Standard include() and require() statements don’t perform such checks, they simply look for the file and load it. Any type of dynamic system setup is going to use these functions quite a bit, and the penalty is incurred each time the function is used. It only takes about a dozen or so calls to see a difference.

Second and more importantly, it feeds laziness. If loading order and structure don’t cause code to fail, then you’re naturally tempted not to worry about them. This leads to unnecessary calls—”Did I load file yet? Ah screw it, I’ll do it again to make sure…”—which feels eerily similar to the rationale of the newbie coder I described above.

I’ve learned that code naturally snowballs in one direction or the other. If you write good clean code, optimize where possible (without going overboard), and completely smash bugs, the code you write and your ability to code will only improve. If instead you opt to ignore formatting, write just until “it works” and move on, and/or create logic that fixes a bug symptom rather than the bug itself, you will not improve and your code will suck.

That’s really the great tragedy; you’ve bypassed an opportunity to potentially improve your code, to potentially improve your own ability. Any shlub can half-ass it; take the high road and do the work. That will put you ahead of said shlubs when it comes time to look for a new job or get a promotion.

I’m not saying any of that is true for you (is it?), but include_once and require_once definitely fall squarely in the lazy coder category as far as I’m concerned.


How focused is your startup idea?

As developers, most of us are always mulling over ideas for potential new services to bring to the world. Who wouldn’t want to say they came up with something Digg, Wikipedia, eBay, etc? And every day, many developers take the plunge on their ideas. Good for them!

However, sometimes I look at new ideas, and I wonder how focused some of these business ideas are. In a world postively saturated with goods and services, it’s imperative that you have a crystal clear image of what your business is going to deliver, how it’s going to deliver, and to whom it will be delivered. If you don’t, you’ve already handicapped your chances of success.

For example, today I got a newsletter from Amazon Web Services, which discussed the finalists in the AWS Start-Up Challenge. All of them had a fair amount of empty marketing fluff, but one really stuck out to me:

Zephyr enables enterprises to manage their test departments more efficiently, boost productivity, reduce costs and provide IT leaders with real-time visibility into all aspects of their software quality cycle.

I don’t use Zephyr, and can’t speak to their quality, but that summary is a veritable buzzword orgasm. I cannot even tell what Zephyr does from that summary. Is it a consulting firm, software product, or a consulting firm using a custom software product? If it’s software, is it hosted or can I run it on my own network? What service(s) do they provide to actually accomplish any of the benefits they outline?

When I hear about companies that try to be all things to a given segment of the market, I’m immediately reminded of a talk by Jason Fried, in a section where he talks about giving up on hard problems:

Software developers love to focus on hard problems, because it makes them feel like they are really good at what they do. Sometimes it’s an interesting challenge, and there’s nothing wrong with hard problems sometimes, but most of the time you want to give up on the hard problems.

You want to look for simple problems, there are an abundance of simple problems to solve, and there’s a huge opportunity for people to continue to solve simple problems. Post-It Notes, [for example]. A lot of people [think] that you can’t make money solving simple problems, but you can…There ’s a lot of examples of really interesting products that are dead-simple solving common problems that are incredibly successful. You don’t have to design the next rocket; you don’t have to design the next algorithm that’s going to search the entire web. There’s lots of other solutions, lots of other things you could be doing.

After checking out Zephyr’s site, I still can’t say for sure whether or not they are solving an excessively hard problem like Jason describes. The Test Management System looks straightforward, but the Management Platform is pretty abstract and obtuse. I read the description and still had no idea who this would be useful to or why.

Sticking with the test system, I think I can do a better job summarizing what they do…

Zephyr provides a software-based collaboration platform tailored specifically to software testing groups. It coordinates wide testing teams with test schedules, and can track and report on the results of each test. Zephyr also provides tools to automate tests, and integrates with bug tracking software like Bugzilla. The software is available for download or as a hosted service.

A tight summary like that does more than clearly convey your businesses purpose to others. By going through the effort of putting a statement like that together, it also ensures that you have that clear image in your head I described earlier. If you don’t have that crystal clear image, put your business down and go define it. How can you know you’re going in the right direction if you don’t determine what that direction actually is?