JavaScript date parsing woes

I just corrected an interesting bug in a web application’s client-side JavaScript code.

How come, most of the time, the string ‘2009-02-01’ gets parsed into a Date object with the correct February 1st, 2009 value, but sometimes results in March 1st, 2009?

This particular piece of code builds a financial periods menu by extracting dates out of some HTML returned by an AJAX request. Here’s what the function looks like – it may not be the best way to construct a date from a string in the form yyyy-mm-dd, but it works:
function makeDateFromIsoString(isoString)
{
if (isoString == null)
return null;
var date = new Date();
date.setFullYear(isoString.substr(0, 4));
date.setMonth(isoString.substr(5, 2) - 1);
date.setDate(isoString.substr(8, 2));
date.setHours(0);
date.setMinutes(0);
date.setSeconds(0);
return date;
}

That is, it works most of the time, but not at the end of some months, as I discovered.

Take yesterday, for instance – March 31st, 2009 – and let’s look at what makeDateFromIsoString(‘2009-02-01’) returned:

  • var date = new Date() created a new Date object, containing the current date and time: March 31st, 2009.
  • date.setFullYear(isoString.substr(0, 4)) changed the year of the data object to  ‘2009‘, so its value stayed the same.
  • date.setMonth(isoString.substr(5, 2) – 1) changed the month of the date object to  ‘02‘ (minus one, because months in JavaScript are zero-based,) so its value became February 31st, 2009. Of course, February 31st doesn’t exists, so because the real date three days after February 28th, 2009 is March 3rd, 2009, the date object now contained that value.
  • So by the the time the code was done with date.setDate(isoString.substr(8, 2)), the date value had become March 1st, 2009.

And this is how February became March, but only during the three last days of March. Interesting twist, isn’t it?

The fix was simple: call setDate() before setMonth().

Viva la Firebug for helping me nail this one down.

Update: In the end, I just replaced the whole function body with this: return new Date(isoString.replace(‘-‘, ‘/’, ‘g’)). Much simpler, and not subject to the above subtle, but interesting nevertheless, bug.

Share

A2Hosting makes another happy customer

I’ve been hosting this blog over at A2Hosting for a while now. I was looking for a reliable, developer-friendly, not too expensive web host, and I must say I’m pretty satisfied so far. It seems that they are providing just the right balance between price, flexibility, and performance.

I found a responsive and knowledgeable customer service that has always proved helpful, their servers’ performance and connectivity has remained top-notch to this day, and their referral program is quite nice, which doesn’t hurt.

So all in all they well deserve the thumbs-up that I’m giving them right now.

Thanks A2Hosting!

Share

Fun with Apache’s mod_rewrite

Part of my duties over at Cobi involve taking care of some web applications we built for our clients. We based those on top of Linux, Apache, MySQL and PHP (the so-called LAMP platform.)

We use Apache’s deflate module to automatically compress the sometimes huge web pages that get sent to the browsers in order to save bandwidth, and gain speed.

Then the need arose to leave some of the pages uncompressed.

It looked quite easy, all is needed after all is to set the Apache’s internal variable no-gzip each time we need to skip the compression step.

Because the URI’s for those uncompressed requests do not follow a particular pattern, I thought that adding a “no-gzip” parameter to the query string and configuring Apache to set (with the help of the module setenvif) the internal variable no-gzip wherever it would encounter it would be enough.

But I was wrong. You can’t do that. Well, at least not with mod_setenvif, because you can’t use the query string with the SetEnvIf directive.

Take #2, I devised that I would then put my “no-gzip” string inside the request URI itself, even if it smelled like a kludge, and then SetEnvIf would be able to see it and do its job.

But it didn’t work either! Because, we happen to also use the rewrite module, with which we rewrite all URI’s so that the web application’s FrontController gets launched for each request. And it seems that mod_rewrite gets to rewrite the request URI before mod_setenvif gets to touch it.

So mod_setenvif was always seeing the FrontController’s URI, without my little “no-gzip” addition, and compression could not be disabled.

So back to my first idea with a “no-gzip” at the beginning of the query string, but with a twist: it is now mod_rewrite, not mod_setenvif which is setting Apache’s no-gzip internal variable:

RewriteCond %{QUERY_STRING} ^no-gzip
RewriteRule ^(.*)$ $1 [NS,E=no-gzip:1,E=dont-vary:1]

Note: it didn’t work until the variable got an actual value assigned. In other words, E=no-gzip didn’t work, but E=no-gzip:1 did.

Share

How DNS works – part 1

Even though the DNS (Domain Name System) protocol isn’t hard to understand, there seems to be quite some confusion about it.

So I’m going to explain a little what it is, why we need it, and how it works. Hopefully I’m going to make it short.

What is DNS?

Roughly speaking, the domain name system is like a phone book, but for computers. It is a big directory for computers to find other computers.

Why do we need DNS?

Why would a computer need a directory to locate another computer, as they are all connected already through the internet, aren’t they?

Well, computers connect to each other in a way that is a bit analogous to the way telephones connect to each other. When making a phone call, you know who you want to talk to, their name, maybe where they physically are located, but you need to dial the right number to reach their phone, because those devices only work with numbers, not names or anything else. In the same way, if I type www.google.com in the address bar of my browser, my computer doesn’t really know to which one, among the millions (billions?) of other computers on the internet, it should connect to. It needs to have the numerical address of Google’s server, what is called its IP address.

When you came to read this particular blog post, your computer took the web address (called a URL) that was mentioned in the link you clicked, queried a DNS server to get the only piece of information that it can use to connect to the machine that hosts this blog, which is: the IP address for nicolascadou.com.

So the domain name system is about names, and their correspondence to numbers. It makes it easy for humans, who won’t remember those pesky numbers unless forced to.

It also eases the job of system administrators, who mention domain names in the configuration of the machines which need to connect to other ones, so that when one server gets moved to another network, they don’t have to reconfigure everything, they just put the new IP address in the right DNS server, and that’s it, no need to modify the configuration of the other machines.

How does DNS work?

First, let’s take a quick look at the anatomy of the names used with The DNS protocol, taking “www.google.com” as an example.

The whole thing is called a hostname. It is a name that refers to the IP address of a computer (the host for Google’s search page.) This hostname is composed of several parts, separated by dots. Technically those parts are called labels, and in our example there are three of them: “com”, “google”, and “www”.

Notice that I listed the labels in reverse order, from right to left.

That may seem counter-intuitive, but those parts represent a cascading, tree-like hierarchy of domains and subdomains which is read from right to left, with the topmost domain being the rightmost one: “com”. This topmost (rightmost) domain has a special name: it is called the TLD (Top Level Domain.)

I said the domain name system is like a phone book, but in reality, it is a huge, hierarchical collection of phone books. This is important, as when the time comes to change DNS records (which are contained in a DNS zone, served by a DNS server) one must find out who’s the authority for that domain, because this party is the only one with the power to do so.

So, for the sake of keeping this blog post short, let’s see right away how the act by which a computer will retrieve the IP address corresponding to a hostname, the act of resolving the hostname by performing a DNS query, is done. The resolver will ask a DNS server for the IP address corresponding to the hostname, wait for an answer, and behind the scenes, the DNS server will itself perform as many DNS queries as needed to get the answer, traversing the DNS hierarchy in this manner:

  1. First, it has to start somewhere, it will query the root DNS servers. All DNS servers must know in advance either the IP addresses of those root servers, or the IP address of another DNS server which know either the root servers, or another DNS server which does, etc. Otherwise it can’t work. The root servers know who is responsible for each TLD. So our DNS server picks one of the root servers and asks: “what is the IP address for www.google.com?
  2. The root server answers: “I don’t know. But I know who’s responsible for the “com” TLD, here are the names and IP addresses of their DNS servers. Pick one.”
  3. So our DNS server proceeds to send the same query to one of those servers: “what is the IP address for www.google.com?
  4. The DNS server responsible for the “com” TLD then answers: “I don’t know. But I know who’s responsible for the “google.com” domain, here are the names and IP addresses of their DNS servers.”
  5. Our DNS server then sends the exact same query to one of those DNS servers at Google: “what is the IP address for www.google.com?
  6. Finally, an answer in given. Google’s DNS server says: “Here’s the IP addresses for www.google.com, pick any one.”

When a DNS server hasn’t got the answer, it can proceed to query directly the next DNS server in the hierarchy, if the resolver asks for it. A DNS server with such capabilities is called a recursive name server.

Conclusion

I hope this summary information is helpful. I think it goes a long way explaining the basics of the domain name system.

I will post a second part in a few days; or weeks, who knows. It will cover domain registration, WHOIS information and others.

Share

Why a blog

I wanted to do the blog thing for quite some time already. I always imagined it would be in the context of my daily job, however, I never thought it would ever be in the form of a public blog.

I work for a fairly small company (Cobi: 20-30 employees) and the department I’m working in is in charge of the ERP solution we offer to SMB’s, as well as the inevitable customizations, extensions, and specialized interfaces with bolt on top of it.

This ERP suite (SouthWare) is quite capable — on the ERP side of things. But it also carries a legacy of being built with a seemingly ancient technology. So we devised different ways to teach this old COBOL dog new HTML, AJAX-y PHP and SQL tricks to bring it into the Internet age.

It’s been working quite well. The modern web interface driving the mature, rock-solid back-end has proven to be a pretty nice combination.

So how did that lead me to the blog idea?

Well, to put it shortly, it’s all about sharing (and recording) knowledge.

Being a small team, we end up doing a bit of everything, but we each necessarily become specialized in our own area of the system. Some feel more comfortable near the back-end and others, with the object-oriented PHP programming, for example.

All of this is fine, but what happens is that when a member of the team leaves the company, for a reason or an other, a big part of the experience this person earned disappears also from the company. Sure, some things are documented but the vast majority of the know-how, the experience, is lost.

This is why I thought that a way for employees to blog their findings into posterity would be a good solution to this problem. The first post to explain why an HTML block-level element’s height is not affected by the height of a floating child block-level element unless it is itself also floated would thankfully save the other developers the time to make experiments (the shoot-in-the-dark kind) and google for a solution.

The blogs would be appropriately aggregated, tagged and indexed, and everybody would get a continuous stream of new things to learn, and an ever expanding knowledge base to dig into. Pretty neat, isn’t it?

When I approached the direction with this idea, however, it got rather quickly turned down for one simple reason: employees would never get to put content online, they would see it more as a burden than anything else — blogs would not fit into the company’s present culture.

Actually, given said culture in this company, I think that’s a rather valid argument. One to which the direction added that it would be nice that some day, this culture would have changed enough that such a project could become a reality.

I am not so sure however, that cultural changes inside a company happen all by themselves, while wishing for them to happen. I think that people have a natural tendency to resist change and as such, efforts of some kind are necessary in order to bring such changes about.

So wishing luck to this project for some distant future is a bit disappointing. It is also some kind of assurance that the current state of affairs will stay as it is for quite some time, if you ask me. Or maybe we are just too small a group to ever hope get enough writing-inclined people to post blog material.

Anyhow, no company-endorsed blog for now, but I still think disseminating knowledge is a good thing, so I decided to do this on my own.

We all are reinventing the wheel over and over, so if I can help somebody find an answer more quickly by having it recorded here, I’ll be happy about having offered this contribution.

So… drum roll… This blog is open!

Share