As a deterrent to my infinite boredom, I've decided to digitize my reminiscence of concert experiences. In other words, I've taken the time to scan all the old concert tickets I have laying around. The oldest ticket I found is from a 1999 Dave Matthew's Concert at Veterans Stadium in Philadelphia. Since then, Dave and company have released 4 more studio albums, I went and saw them 11 more times, and Veterans Stadium has been imploded and is now a parking lot. I feel old.
-
18 Jan 2006 Bittersweet Nostalgia
-
17 Jan 2006 Web 2.0 Whining
I have nothing but the utmost respect for Mr. Jeffrey Zeldman. If it wasn't for him and that beautiful orange book he wrote back in 2003, I wouldn't be half as motivated to create clean content for the web. That being said, I'm a bit disappointed that he has fallen victim to the nonsensical whining of anti-web-2.0 zealots. I don't see the point and I wish it would all just go away.
As I've said before, I'm not a fan of buzzwords and there's nothing I hate more than a middle manager with a head full of technologies he knows nothing about. But let's forget about all that and think about what it is we are trying to accomplish. I don't know about you, but I would like to make better web sites. Web sites with better usability.
Let's face it, Tim Berners-Lee never fathomed the web would be used the way we use it today when he was sitting behind a NeXTcube. The HTML protocol was just not made to support rich e-mail clients that check our spelling as we type, or maps that allow us to drag them around transparently fetching more information from the server in the background. I don't see how anybody could disagree with the fact that these features enhance a user's experience on the web, and they would simply not be possible without AJAX or some other still undiscovered technology.
I'm also sick of hearing that AJAX provides nothing new. That AJAX is the same old javascript with fancy API's written on top. This is simply not true. AJAX is a collection of technologies that, until recently, nobody thought to stick together. Nobody is claiming the javascript to be interesting. It's the way javascript is being used to invoke other available resources, namely the XmlHttpRequest object, that makes things interesting. I will agree that these technologies were available in some capacity since Internet Explorer 5, but who cares! Do we disdain AJAX as a technology just because it is a collection of existing technologies that nobody had the mental capacity and creativity to stick together before now? I think not.
The sooner people stop complaining about the improper use of 'Web 2.0' buzzwords and start thinking about what this technology (or concept, or collection of technologies, or whatever you wish to call it,) gives us as web developers and how we can embrace it and enhance it, the better off we will be, and the better off the users of our sites will be. I don't care if venture capitalists are backing a hundred Ruby-based AJAX-driven social networking sites. I don't care about the money involved or the possibility of another dot-com bubble. I just care about the technology. I'm excited about what this technology offers us and I look forward to watching it shape the future of the web.
-
05 Jan 2006 Portable Time Zones In Rails Applications
It seems like such a simple concept: I live in New Jersey; therefore I would like all of the dated material on my site to be displayed and managed in the Eastern Time zone. I'm sure some of you are wondering why I'm wasting my time writing about such a simple concept. Set the server time zone to US/Eastern and all should be well, right? Not so fast. Suppose your server is in California and you don't have the option of changing the time zone.
This is the situation I encountered recently while putting this site together to be hosted by Dreamhost. After thinking way too long about how to solve this problem, I'd like to discuss my solution for maintaining flexible, time zone independent dates in Rails applications.
The Problem
Let's take a look at what we're trying to accomplish:
Time.now
andmysql>sysdate()
will produce times in the Pacific Time zone, but we would like to store and display these times in the Eastern Time zone.- We would like all of our dates to be managed in the Eastern Time zone.
That's it. Seems simple enough right?
What most people will probably do at first
OK, the server is on Pacific Time, so all dates generated on the system clock will be in Pacific Time. The Pacific Time zone is exactly 3 hours behind the Eastern Time zone, so the problem can be fixed by simply adding 3 hours to all the dates being generated by the System clock. Your SQL will change to:
mysql>date_add(sysdate(), interval 3 hour);
and, more appropriately for a Rails application, Your Ruby code will change to:
time_in_eastern = Time.now() + (60 * 60 * 3)
So we're close to coming up with a solution: our users will give us all times in the Eastern Time zone, and all system clock generated times will be converted to the Eastern Time zone by adding 3 hours. In researching message boards and articles on the subject, it seems like this is probably the most popular solution (not necessarily only for Rails apps, but in general.) However, we should consider the following drawbacks to this solution:
strftime("%Z")
will still display the Pacific Time zone by default for any dates retrieved with ActiveRecord.- Your application will be hard-coded with a 3 hour interval difference. What if webspace becomes ridiculously cheap in Russia and you'd like to move your application? (Hey, music is, so why not web space?)
- If you decide at a later time that you would like to work with your dates in some other time zone, say Central time, you will need to change the time interval in your code to 2 instead of 3, and subtract an hour from all the dates that have been stored already. Not exactly portable.
Where does this leave us?
OK, so
strftime("%Z")
is displaying Pacific Time, even though we are sure that all of our times are stored as Eastern Time. Believe it or not, this can be fixed with a simple configuration of your application. Whooaa! A configuration...In a Rails app? But that's impossible!The Rails team prides itself on 'convention over configuration,' and for the most part, following the conventions will lead to predictable results. However, in this situation, the convention is for ActiveRecord to default to using whatever time zone your server is in when retrieving dates. This is a problem for us, since we would like to work with our dates in some other time zone. The solution requires us to add an entry to the bottom of the environment.rb file (under the /public directory):
This will tell ActiveRecord to retrieve all dates as Eastern Time Zone dates, regardless of the server's actual time zone.ActiveRecord::Base.default_timezone = :est
Now all of the bases are covered, and we have come up with a first run solution to the problem. If this solution works for you, and you are happy with keeping track of all these conversions, then go for it. I personally would like a better solution. A solution that would allow me to move my application, or my database, to a server living in a different time zone. I would also like the freedom to change my mind as to what time zone my application prefers to work in (think about selling your application to a customer. Shouldn't they choose the time zone?)
Enter UTC Time
UTC, or Universal Time Code, is a modern day synonym for Greenwich Mean Time (they are not exactly the same, but for our purposes here, they can be thought of as the same.) If we store all of our dates in UTC, then we have the freedom of moving our application and our database to servers in any time zone. Additionally, we can use an environment variable to tell our application what time zone to use when generating timestamps off of the system clock. The Ruby Time API is written to transparently handle all of the conversions between our local time zone dates, and the UTC dates we will be storing in the database.
Let's Implement
First we'll edit our environment.rb file to inform ActiveRecord that our dates are stored in UTC:
Now, we'll add an additional entry to the environment.rb file to set up an environment variable informing rails that the local time zone should be Eastern Time:ActiveRecord::Base.default_timezone = :utc
And thats it! Our application is now configured for portable time zones. As a best practice, I would recommend appending '_UTC' to the end of the database column name responsible for storing your dates. This will make it obvious to anyone viewing the table that the dates are stored in UTC.ENV['TZ'] = 'US/Eastern'
Common Usage of The Time API
Our app is now configured and ready to roll, so lets look at how we can easily work with our new portable dates with the use of the Ruby Time library. For the following code snippets, let's assume we have a 'Blog' model with a column 'date_added_utc'
-
Time.now
-> The current timestamp in Eastern Time. -
Time.now.utc
-> The UTC representation of the current timestamp. This should be used to convert times to UTC before being stored in the database. -
Blog.find(id).date_added.utc.localtime
-> The Eastern Time zone representation of the date_added_utc field. This should be used when retrieving dates from the database. -
Blog.find(id).date_added_utc.utc?
-> Evaluates to True. Use this method to test if dates are in UTC form.
Aren't We Forgetting Something?
When discussing the problems with time zones, we said that
mysql>sysdate()
generated times in the wrong time zone. We haven't said a word about it since. I personally feel that you shouldn't ever have to use this in your Rails apps, since you would be straying from the ORM-driven path provided by ActiveRecord. However, I realize that some developers might wish to use straight SQL in their applications, so I'm here to help. If you would like to generate current UTC timestamps in sql, you can use theconvert_tz
construct (If your using MySql, this is only available in versions 4.1.3 and greater.) The syntax is as follows:
This will return the conversion of the current system time from Pacific Time to UTC time. Remember, we are once again at the mercy of the location of the database server. In order to make this a bit more maintainable, we could use a sepaarate environment variable to specify the time zone of the database server so it won't be hard-coded in our application. But again, my advice is to not use database-generated timestamps in favor of working directly in Ruby. If you disagree, then this should give you some direction as to how to use them practically to keep your application maintainable.mysql>convert_tz(systime(), 'PST', 'UTC')