SVG D3.js - 時間格式 ( Time Formatting )

我們都知道在 javascript 裏頭可以抓取電腦的當下的時間 (new date()),或是在裏頭設定某個時間,但如果要把產生的時間進行格式化,常常要耗費不少字串處理的時間,在 d3.js 裏頭,有提供不少的時間格式的 API ,讓我們可以輕鬆的產生我們所需要的格式。

來看一下關於定義時間格式,有哪些 API 可以使用:

  • d3.time.format(specifier)
  • format(date)
  • format.parse(string)
  • d3.time.format.multi(formats)
  • d3.time.format.utc(specifier)
  • d3.time.format.iso

d3.time.format(specifier)、format(date)

這兩個 API 要一起看,雖然都是 format ,不過意思卻不相同,time.format 主要是定義時間的格式是什麼,而 format,則是將我們要格式化的時間套入,下面是 d3.js 所有 time.format 的格式:

至於要如何使用呢?可以參考下面的範例,先把宣告一個 d3.js 的 time 物件,制定好格式,再將時間放入,就會變成相關格式的時間囉!( 範例:svg-d3-11-time-demo1.html )

var d = new Date('2014,12,01,12:16:05');

var _a = d3.time.format("%a");
var _A = d3.time.format("%A");
var _b = d3.time.format("%b");
var _B = d3.time.format("%B");
var _c = d3.time.format("%c");
var _d = d3.time.format("%d");
var _e = d3.time.format("%e");
var _H = d3.time.format("%H");
var _I = d3.time.format("%I");
var _j = d3.time.format("%j");
var _m = d3.time.format("%m");
var _M = d3.time.format("%M");
var _L = d3.time.format("%L");
var _p = d3.time.format("%p");
var _S = d3.time.format("%S");
var _U = d3.time.format("%U"); 
var _w = d3.time.format("%w");
var _W = d3.time.format("%W");
var _x = d3.time.format("%x");
var _X = d3.time.format("%X");
var _y = d3.time.format("%y");
var _Y = d3.time.format("%Y");
var _Z = d3.time.format("%Z");

console.log(d); //Mon Dec 01 2014 12:16:05 GMT+0800 (台北標準時間)

console.log(_a(d)); //Mon
console.log(_A(d)); //Monday
console.log(_b(d)); //Dec
console.log(_B(d)); //December
console.log(_c(d)); //Mon Dec  1 12:16:05 2014
console.log(_d(d)); //01
console.log(_e(d)); // 1
console.log(_H(d)); //12
console.log(_I(d)); //12
console.log(_j(d)); //335
console.log(_m(d)); //12
console.log(_M(d)); //16
console.log(_L(d)); //000
console.log(_p(d)); //PM
console.log(_S(d)); //05
console.log(_U(d)); //48
console.log(_w(d)); //1
console.log(_W(d)); //48
console.log(_x(d)); //12/01/2014
console.log(_X(d)); //12:16:05
console.log(_y(d)); //14
console.log(_Y(d)); //2014
console.log(_Z(d)); //+0800

了解運作原理之後,接著就可以利用組合的方式,做出我們想要的格式。( 範例:svg-d3-11-time-demo2.html )

var Ymd = d3.time.format("%Y-%m-%d");
var pIM = d3.time.format("(%p)%I:%M");

console.log(Ymd(d)); //2014-12-16
console.log(pIM(d)); //(PM)12:16

format.parse(string)

針對經由 d3.time.format 的物件字串,轉換為原始的時間格式,如果沒有經過 time 格式化,出來可能會報錯獲釋返回 null。( 範例:svg-d3-11-time-demo3.html )

var _x = d3.time.format("%x");

var a=_x(d);

var dd = '2014/12/30 12:05:18';

console.log(a);            //12/01/2014
console.log(_x.parse(a));  //Mon Dec 01 2014 00:00:00 GMT+0800 (台北標準時間)
console.log(_x.parse(dd)); //null

d3.time.format.multi(formats)

multi 有多選或複合的意思,這個 API 主要針對時間的尺度而設計,可以讓時間根據不同的尺度,自動從多個格式中挑出最適當的格式 ( 返回 true 即套用該格式 ),因此當從年分逐漸縮減到小時或分鐘,都可以在同一個畫面中呈現,在下方的範例中,time.scale 的用法就像之前提過的 scale 一樣,把一段時間放到一個範圍內顯示,而 customTimeFormat 就是負責要顯示那些時間出來,因為這個範例是一年份,所以左右就變成了年份,中間就是月份。 ( 可以參考 d3 原作者範例,或 svg-d3-11-time-demo4.html )

var customTimeFormat = d3.time.format.multi([
  [".%L", function(d) { return d.getMilliseconds(); }],
  [":%S", function(d) { return d.getSeconds(); }],
  ["%I:%M", function(d) { return d.getMinutes(); }],
  ["%I %p", function(d) { return d.getHours(); }],
  ["%a %d", function(d) { return d.getDay() && d.getDate() != 1; }],
  ["%b %d", function(d) { return d.getDate() != 1; }],
  ["%B", function(d) { return d.getMonth(); }],
  ["%Y", function() { return true; }]
]);

var margin = {top: 250, right: 40, bottom: 250, left: 40},
    width = 960 - margin.left - margin.right,
    height = 500 - margin.top - margin.bottom;

var x = d3.time.scale()
    .domain([new Date(2012, 0, 1), new Date(2013, 0, 1)])
    .range([0, width]);

var xAxis = d3.svg.axis()
    .scale(x)
    .tickFormat(customTimeFormat);

var svg = d3.select("body").append("svg")
    .attr("width", width + margin.left + margin.right)
    .attr("height", height + margin.top + margin.bottom)
  .append("g")
    .attr("transform", "translate(" + margin.left + "," + margin.top + ")");

svg.append("g")
    .attr("class", "x axis")
    .attr("transform", "translate(0," + height + ")")
    .call(xAxis);

SVG D3.js - 時間格式 ( Time Formatting )

當我們把時間間隔縮減,就會發現時間軸的格式自動變化了。( 範例:svg-d3-11-time-demo5.html )

var x = d3.time.scale()
.domain([new Date(2012, 0, 1), new Date(2012, 3, 1)])
.range([0, width]);

SVG D3.js - 時間格式 ( Time Formatting )

d3.time.format.utc(specifier)

utc 是標準定位時間格式 ( UTC time ),以台灣來說,就是 UTC+8:00,utc 對於跨時區或涉及多個國家地區的時候,設定為 utc 的時間會比較方便,UTC 傳回參數日期的 GMT ( 由 1970年1月1日零時零分計起,以微秒為單位 )

d3.time.format.iso

一個完整的 ISO 8601 UTC 時間格式為 %Y-%m-%dT%H:%M:%S.%LZ。( 範例:svg-d3-11-time-demo6.html )

var d = new Date();

var f = d3.time.format("%c");
var u = d3.time.format.utc(f(d));
var i = d3.time.format.iso(d);

console.log(d);    //Mon Dec 29 2014 23:15:05 GMT+0800 (台北標準時間)
console.log(f(d)); //Mon Dec 29 23:15:05 2014
console.log(u);    //Mon Dec 29 23:15:05 2014
console.log(i);    //2014-12-29T15:15:05.665Z

小結

其實定義時間格式沒有太大難度,因為定義格式,目的其實也是為了在顯示圖表的時候,可以更為清楚,所以在這篇了解時間格式之後,會用其他篇幅來繼續介紹如何運用這些時間格式,創造漂亮的圖表。

有興趣瞧瞧其他新文章嗎?