In my neck of the woods, it's customary to write the date as day - month – year. E.g 23-12-2012. But in the United States the more common format would be 12-23-2012. Likewise, the data may be in formats that name the months or weekdays (E.g. January, Tuesday) or combine dates and time together (E.g. 2012-12-23 15:45:32). So, if we were to attempt to try to load in some data and to try and get D3 to recognise it as date / time information, we really need to tell it what format the date / time is in.
Now, you might be asking yourself what's the point? All you want to do is give it a number and it can sort it out somehow. Well, that is true, but if you want to really bring out the best in your data and to keep maximum flexibility in representing it on the screen, you will want to D3 to play to it's strengths. And one of those is being able to adjust dynamically with variable time values.
Time for a little demonstration.
I will change our data.tsv file that we use to load data to graph so that it only includes two points. The first one and the last one with a separation of a month and a bit.
date close 1-May-12 58.13 26-Mar-12 606.98The graph now looks like this;
So, nothing too surprising here, a very simple graph (note the time scale on the x axis).
But now I will change the later date in the data.tsv file so that it is a lot closer to the starting date;
date close 29-Mar-12 58.13 26-Mar-12 606.98So, just a three day difference. Let's see what happens.
Now, one more time for giggles.
This time we'll stretch the interval out by a few years.
date close 29-Mar-21 58.13 26-Mar-12 606.98and the result is...
Hopefully that's enough encouragement to impress upon you that formatting the time is a REALLY good thing to get right and trust me, it will never fail to impress :-).
So, back to formatting.
var parseDate = d3.time.format("%d-%b-%y").parse;
This line is used when the data.forEach(function(d) portion of the code that we looked at a couple of pages back used d.date = parseDate(d.date) as a way to take a date in a specific format and to get it recognised by D3. In effect it said take this value that is supposedly a date and make it into a value I can understand.
The function used is the d3.time.format(specifier) function where the specifier in this case is the mysterious combination of characters '%d-%b-%y'. The good news is that these are just a combination of directives specific for the type of date we are presenting.
The '%' signs are used as prefixes to each separate format type and the '-' signs are literals for the actual '-' signs that appear in the date to be parsed.
The 'd' refers to a zero-padded day of the month as a decimal number [01,31].
The 'b' refers to an abbreviated month name.
And the 'y' refers to the year with century as a decimal number.
If we look at a subset of the data from the data.tsv file we see that indeed, the dates therein are formatted in this way.
So that's all well and good, but what if your data isn't formatted exactly like that?
Good news. There area a heap of different formatters for different ways of telling time and you get to pick and choose what you want. Check out the Time Formatting page on the D3 Wiki for a the authoritative list and some great detail, but the following is the list of currently available formatters (from the d3 wiki);
- %a - abbreviated weekday name.
- %A - full weekday name.
- %b - abbreviated month name.
- %B - full month name.
- %c - date and time, as "%a %b %e %H:%M:%S %Y".
- %d - zero-padded day of the month as a decimal number [01,31].
- %e - space-padded day of the month as a decimal number [ 1,31].
- %H - hour (24-hour clock) as a decimal number [00,23].
- %I - hour (12-hour clock) as a decimal number [01,12].
- %j - day of the year as a decimal number [001,366].
- %m - month as a decimal number [01,12].
- %M - minute as a decimal number [00,59].
- %p - either AM or PM.
- %S - second as a decimal number [00,61].
- %U - week number of the year (Sunday as the first day of the week) as a decimal number [00,53].
- %w - weekday as a decimal number [0(Sunday),6].
- %W - week number of the year (Monday as the first day of the week) as a decimal number [00,53].
- %x - date, as "%m/%d/%y".
- %X - time, as "%H:%M:%S".
- %y - year without century as a decimal number [00,99].
- %Y - year with century as a decimal number.
- %Z - time zone offset, such as "-0700".
- %% - a literal "%" character.
As an example, if you wanted to input date / time formatted as a generic MySQL 'YYYY-MM-DD HH:MM:SS' TIMESTAMP format the D3 parse script would look like;
parseDate = d3.time.format("%Y-%m-%d %H:%M:%S").parse;