diff --git a/IPython/html/static/components b/IPython/html/static/components
index a80ac7a..b3909af 160000
--- a/IPython/html/static/components
+++ b/IPython/html/static/components
@@ -1 +1 @@
-Subproject commit a80ac7a2f6d045e3903d3c9e189a10cc96255b05
+Subproject commit b3909af1b61ca7a412481759fdb441ecdfb3ab66
diff --git a/IPython/html/static/notebook/js/menubar.js b/IPython/html/static/notebook/js/menubar.js
index 67e0d5b..9952f04 100644
--- a/IPython/html/static/notebook/js/menubar.js
+++ b/IPython/html/static/notebook/js/menubar.js
@@ -7,7 +7,8 @@ define([
     'base/js/utils',
     'notebook/js/tour',
     'bootstrap',
-], function(IPython, $, utils, tour) {
+    'moment',
+], function(IPython, $, utils, tour, bootstrap, moment) {
     "use strict";
     
     var MenuBar = function (selector, options) {
@@ -336,7 +337,7 @@ define([
                 $("<li/>").append(
                     $("<a/>")
                     .attr("href", "#")
-                    .text(d.format("mmm dd HH:MM:ss"))
+                    .text(moment(d).format("LLLL"))
                     .click(function () {
                         that.notebook.restore_checkpoint_dialog(checkpoint);
                     })
diff --git a/IPython/html/static/notebook/js/notificationarea.js b/IPython/html/static/notebook/js/notificationarea.js
index 4fddb09..2426cef 100644
--- a/IPython/html/static/notebook/js/notificationarea.js
+++ b/IPython/html/static/notebook/js/notificationarea.js
@@ -7,7 +7,8 @@ define([
     'base/js/utils',
     'base/js/dialog',
     'notebook/js/notificationwidget',
-], function(IPython, $, utils, dialog, notificationwidget) {
+    'moment'
+], function(IPython, $, utils, dialog, notificationwidget, moment) {
     "use strict";
 
     var NotificationArea = function (selector, options) {
@@ -221,7 +222,7 @@ define([
             var msg = "Checkpoint created";
             if (data.last_modified) {
                 var d = new Date(data.last_modified);
-                msg = msg + ": " + d.format("HH:MM:ss");
+                msg = msg + ": " + moment(d).format("HH:mm:ss");
             }
             nnw.set_message(msg, 2000);
         });
diff --git a/IPython/html/static/notebook/js/savewidget.js b/IPython/html/static/notebook/js/savewidget.js
index 7daddcd..0a7cff1 100644
--- a/IPython/html/static/notebook/js/savewidget.js
+++ b/IPython/html/static/notebook/js/savewidget.js
@@ -7,8 +7,8 @@ define([
     'base/js/utils',
     'base/js/dialog',
     'base/js/keyboard',
-    'dateformat',
-], function(IPython, $, utils, dialog, keyboard, dateformat) {
+    'moment',
+], function(IPython, $, utils, dialog, keyboard, moment) {
     "use strict";
 
     var SaveWidget = function (selector, options) {
@@ -16,6 +16,7 @@ define([
         this.notebook = undefined;
         this.selector = selector;
         this.events = options.events;
+        this._checkpoint_date = undefined;
         this.keyboard_manager = options.keyboard_manager;
         if (this.selector !== undefined) {
             this.element = $(selector);
@@ -51,11 +52,11 @@ define([
             that.set_save_status('Autosave Failed!');
         });
         this.events.on('checkpoints_listed.Notebook', function (event, data) {
-            that.set_last_checkpoint(data[0]);
+            that._set_last_checkpoint(data[0]);
         });
 
         this.events.on('checkpoint_created.Notebook', function (event, data) {
-            that.set_last_checkpoint(data);
+            that._set_last_checkpoint(data);
         });
         this.events.on('set_dirty.Notebook', function (event, data) {
             that.set_autosaved(data.value);
@@ -123,7 +124,7 @@ define([
         var nbname = this.notebook.get_notebook_name();
         document.title = nbname;
     };
-    
+
     SaveWidget.prototype.update_address_bar = function(){
         var base_url = this.notebook.base_url;
         var nbname = this.notebook.notebook_name;
@@ -142,19 +143,87 @@ define([
         this.element.find('span#autosave_status').text(msg);
     };
 
-    SaveWidget.prototype.set_checkpoint_status = function (msg) {
-        this.element.find('span#checkpoint_status').text(msg);
+    SaveWidget.prototype._set_checkpoint_status = function (human_date, iso_date) {
+        var el = this.element.find('span#checkpoint_status')
+        if(human_date){
+            el.text("Last Checkpoint: "+human_date).attr('title',iso_date);
+        } else {
+            el.text('').attr('title','no-checkpoint')
+        }
     };
 
-    SaveWidget.prototype.set_last_checkpoint = function (checkpoint) {
-        if (!checkpoint) {
-            this.set_checkpoint_status("");
+    // compute (roughly) the remaining time in millisecond until the next
+    // moment.js relative time update of the string, which by default 
+    // happend at 
+    //  (a few seconds ago) 
+    //  - 45sec, 
+    //  (a minute ago) 
+    //  - 90sec,
+    //      ( x minutes ago) 
+    //      - then every minutes until
+    //  - 45 min,
+    //      (an hour ago) 
+    //  - 1h45, 
+    //      (x hours ago )
+    //      - then every hours
+    //  - 22 hours ago
+    var _next_timeago_update = function(deltatime_ms){
+        var s = 1000; 
+        var m = 60*s;
+        var h = 60*m;
+
+        var mtt = moment.relativeTimeThreshold;
+
+        if(deltatime_ms < mtt.s*s){
+            return mtt.s*s-deltatime_ms;
+        } else if (deltatime_ms < (mtt.s*s+m)) {
+            return (mtt.s*s+m)-deltatime_ms;
+        } else if (deltatime_ms < mtt.m*m){
+            return m;
+        } else if (deltatime_ms < (mtt.m*m+h)){
+            return (mtt.m*m+h)-deltatime_ms;
+        } else  {
+            return h;
+        }
+
+
+    }
+
+    SaveWidget.prototype._regularly_update_checkpoint_date = function(){
+       if (!this._checkpoint_date) {
+            this.set_checkpoint_status(null);
+            console.log('no checkpoint done');
             return;
         }
-        var d = new Date(checkpoint.last_modified);
-        this.set_checkpoint_status(
-            "Last Checkpoint: " + dateformat(d,'mmm dd HH:MM')
-        );
+        var chkd = moment(this._checkpoint_date);
+        var longdate = chkd.format('llll');
+
+        var that = this;
+        var recall  = function(t){
+            // recall slightly later (1s) as long timeout in js might be imprecise,
+            // and you want to be call **after** the change of formatting should happend.
+            return setTimeout($.proxy(that._regularly_update_checkpoint_date, that),(t+1000))
+        }
+        var tdelta = Math.ceil(new Date()-this._checkpoint_date);
+
+        // update regularly for the first 6hours and show
+        // <x time> ago
+        if(tdelta < tdelta < 6*3600*1000){  
+            recall(_next_timeago_update(tdelta));
+            this._set_checkpoint_status( chkd.fromNow(), longdate);
+        // otherwise update every hour and show
+        // <Today | yesterday|...> at hh,mm,ss
+        } else  {
+            recall(1*3600*1000)
+            this._set_checkpoint_status( chkd.calendar(), longdate);
+        }
+
+    }
+
+    SaveWidget.prototype._set_last_checkpoint = function (checkpoint) {
+        this._checkpoint_date = new Date(checkpoint.last_modified);
+        this._regularly_update_checkpoint_date();
+
     };
 
     SaveWidget.prototype.set_autosaved = function (dirty) {
diff --git a/IPython/html/static/notebook/less/savewidget.less b/IPython/html/static/notebook/less/savewidget.less
index 5b7c6ef..59e4757 100644
--- a/IPython/html/static/notebook/less/savewidget.less
+++ b/IPython/html/static/notebook/less/savewidget.less
@@ -31,4 +31,4 @@ span#checkpoint_status, span#autosave_status {
     }
 }
 
-  
\ No newline at end of file
+  
diff --git a/IPython/html/templates/page.html b/IPython/html/templates/page.html
index fc38982..ea0a89d 100644
--- a/IPython/html/templates/page.html
+++ b/IPython/html/templates/page.html
@@ -28,6 +28,7 @@
             dateformat: 'dateformat/date.format',
             jqueryui: 'components/jquery-ui/ui/minified/jquery-ui.min',
             highlight: 'components/highlight.js/build/highlight.pack',
+            moment: "components/moment/moment",
           },
           shim: {
             underscore: {
diff --git a/setupbase.py b/setupbase.py
index 269c02d..f2f20d1 100644
--- a/setupbase.py
+++ b/setupbase.py
@@ -160,6 +160,8 @@ def find_package_data():
         pjoin(components, "marked", "lib", "marked.js"),
         pjoin(components, "requirejs", "require.js"),
         pjoin(components, "underscore", "underscore-min.js"),
+        pjoin(components, "moment", "moment.js"),
+        pjoin(components, "moment", "min","moment.min.js"),
     ])
     
     # Ship all of Codemirror's CSS and JS