]> git.ipfire.org Git - thirdparty/moment.git/commitdiff
updated readme to reflect update to 0.3.0
authorTim Wood <washwithcare@gmail.com>
Wed, 16 Mar 2011 17:31:39 +0000 (10:31 -0700)
committerTim Wood <washwithcare@gmail.com>
Wed, 16 Mar 2011 17:31:39 +0000 (10:31 -0700)
README.markdown
lib/underscore.date.js
lib/underscore.date.min.js

index affd23ba9aa536071a5e5e3f6d629611c139defe..b853a97031460ffcc1cca7726ed5c88ef772b806 100644 (file)
@@ -5,19 +5,108 @@ Author: Tim Wood
 
 Underscore.date is a JavaScript Date utility library built on top of [Underscore.js](http://documentcloud.github.com/underscore/)
 
-It is composed of 2 sections: extending Date.prototype and adding underscore mixins.
+It adds utility functions for working with Date objects without extending `Date.prototype`.
 
-Date.prototype functions
-========================
+In addition to the date creation and manipulation functions, there are a few functions for displaying a date in human readable formats.
 
-Date.prototype.humanize(format)
--------------------------------
+    _.formatDate(new Date(2010, 1, 14, 15, 25, 50, 125), "dddd, MMMM Do YYYY, h:mm:ss a"); // "Sunday, February 14th 2010, 3:25:50 pm"
+    _.fromNow(new Date(2010, 1, 14, 15, 25, 50, 125)); // "20 days ago"
 
-Date.humanize returns a human readable string for a Date based on the format string that was passed in.
 
-    var date = new Date(2010, 1, 14, 15, 25, 50, 125);
-    date.humanize("dddd, MMMM Do YYYY, h:mm:ss a"); // "Sunday, February 14th 2010, 3:25:50 pm"
-    date.humanize("ddd, hA"); // "Sun, 3PM"
+Date Input Options 
+==================
+
+Wherever the `dateInput` parameter is specified in the functions below, you can pass any of the following data types in.
+
+Array
+------
+`[2010, 1, 14, 15, 25, 50, 125]`
+
+The array should mirror the parameters passed into [Date.UTC()](https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Date/UTC).
+
+`[year, month, date, hours, minutes, seconds, milliseconds]`
+
+Any value past the year is optional, and will default to the lowest possible number.
+
+Date 
+----
+`new Date(2010, 1, 14, 15, 25, 50, 125)`
+
+Any valid `Date` object. For more information on `Date` objects, see [the JavaScript Date documentation at MDN](https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Date)
+
+String
+------
+`"Dec 25, 1995"`
+A string that can be parsed by [Date.parse()](https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Date/parse).
+
+Number
+------
+`1300291340510`
+
+An integer value representing the number of milliseconds since 1 January 1970 00:00:00 UTC.
+
+undefined
+---------
+`undefined`
+
+If no value is passed to a 'dateInput' parameter, it will default to the current time using `new Date()`.
+
+    _.date() === new Date()
+
+Chaining 
+========    
+
+You can chain functions by using the underscore `chain()` and `value()` functions.
+
+    _([2010, 1, 14, 15, 25, 50, 125]).chain().date().addTime({ms:200,s:10,m:10,h:2,d:3,M:2,y:3}).formatDate("MMMM Do YYYY, h:mm:ss a").value() // "April 17th 2013, 5:36:00 pm"
+
+Date Functions
+==============
+
+_.addTime(dateInput, timeToAdd) `:Date`
+--------------------------------------
+
+Returns `dateInput` plus the time in the `timeToAdd` object. 
+
+The `timeToAdd` object should have key value pairs as shown below.
+
+    {
+        ms:200, // milliseconds
+        s:10, // seconds
+        m:10, // minutes (note: lowercase)
+        h:2, // hours
+        d:3, // days
+        M:2, // months (note: uppercase)
+        y:3 // years
+    }
+
+All the parameters are optional. Also, there are no upper limits for the values, so you can overload any of the parameters.
+
+    {ms:1000000} // a million milliseconds
+    {d:360} // 360 days
+
+### Special considerations for months and years
+
+If the day of the month on the original date is greater than the number of days in the final month, the day of the month will change to the last day in the final month.
+
+Example:
+    
+    _.date([2010, 0, 31]) // January 31
+    _.addTime([2010, 0, 31], {M:1}) // February 28
+
+_.date(dateInput) `:Date`
+-------------------------
+
+Returns a `Date` based on the dateInput parameters specified above.
+
+_.formatDate(dateInput, string) `:String`
+-----------------------------------------
+
+`_.formatDate()` returns a human readable string for a Date based on the format string that was passed in.
+
+    _.formatDate(new Date(2010, 1, 14, 15, 25, 50, 125), "dddd, MMMM Do YYYY, h:mm:ss a"); // "Sunday, February 14th 2010, 3:25:50 pm"
+    _.formatDate(new Date(2010, 1, 14, 15, 25, 50, 125), "ddd, hA"); // "Sun, 3PM"
 
 The formats are created by creating a string of replacable characters.
 
@@ -28,7 +117,7 @@ The formats are created by creating a string of replacable characters.
         <th>Output</th>
     </tr>
     <tr>
-       <td colspan="2" align="center">Month</td>
+       <td colspan="2"><b>Month</b></td>
     </tr>
     <tr>
         <td>M</td>
@@ -51,7 +140,7 @@ The formats are created by creating a string of replacable characters.
         <td>January February ... November December</td>
     </tr>
     <tr>
-       <td colspan="2" align="center">Day of Month</td>
+       <td colspan="2"><b>Day of Month</b></td>
     </tr>
     <tr>
         <td>D</td>
@@ -66,7 +155,7 @@ The formats are created by creating a string of replacable characters.
         <td>01 02 ... 30 31</td>
     </tr>
     <tr>
-       <td colspan="2" align="center">Day of Year</td>
+       <td colspan="2"><b>Day of Year</b></td>
     </tr>
     <tr>
         <td>DDD</td>
@@ -81,7 +170,7 @@ The formats are created by creating a string of replacable characters.
         <td>001 002 ... 364 365</td>
     </tr>
     <tr>
-       <td colspan="2" align="center">Day of Week</td>
+       <td colspan="2"><b>Day of Week</b></td>
     </tr>
     <tr>
         <td>d</td>
@@ -100,7 +189,7 @@ The formats are created by creating a string of replacable characters.
         <td>Sunday Monday ... Friday Saturday</td>
     </tr>
     <tr>
-       <td colspan="2" align="center">Week of Year</td>
+       <td colspan="2"><b>Week of Year</b></td>
     </tr>
     <tr>
         <td>w</td>
@@ -115,7 +204,7 @@ The formats are created by creating a string of replacable characters.
         <td>01 02 ... 52 53</td>
     </tr>
     <tr>
-       <td colspan="2" align="center">Year</td>
+       <td colspan="2"><b>Year</b></td>
     </tr>
     <tr>
         <td>YY</td>
@@ -126,7 +215,7 @@ The formats are created by creating a string of replacable characters.
         <td>1970 1971 ... 2029 2030</td>
     </tr>
     <tr>
-       <td colspan="2" align="center">AM/PM</td>
+       <td colspan="2"><b>AM/PM</b></td>
     </tr>
     <tr>
         <td>A</td>
@@ -137,7 +226,7 @@ The formats are created by creating a string of replacable characters.
         <td>am pm</td>
     </tr>
     <tr>
-       <td colspan="2" align="center">Hour</td>
+       <td colspan="2"><b>Hour</b></td>
     </tr>
     <tr>
         <td>H</td>
@@ -156,7 +245,7 @@ The formats are created by creating a string of replacable characters.
         <td>01 02 ... 11 12</td>
     </tr>
     <tr>
-       <td colspan="2" align="center">Minute</td>
+       <td colspan="2"><b>Minute</b></td>
     </tr>
     <tr>
         <td>m</td>
@@ -167,7 +256,7 @@ The formats are created by creating a string of replacable characters.
         <td>00 01 ... 58 59</td>
     </tr>
     <tr>
-       <td colspan="2" align="center">Second</td>
+       <td colspan="2"><b>Second</b></td>
     </tr>
     <tr>
         <td>s</td>
@@ -178,76 +267,102 @@ The formats are created by creating a string of replacable characters.
         <td>00 01 ... 58 59</td>
     </tr>
 </table>
+   
+_.fromNow(dateInput1, [dateInput2]) `:String`
+---------------------------------------------
 
-Underscore mixin functions
-==========================
-    
-_.now(asTimestamp)
-------------------
+Returns a string as time from now.
 
-Returns the current date. 
+`dateInput2` is optional, and if left out will default to _.now(true).
 
-Pass `true` to return a UNIX timestamp, otherwise it will return a javascript Date object.
+The base strings can be customized with `_.customizeDate()`.
 
-_.relativetime(milliseconds)
-----------------------------
+Examples:
 
-Returns a string as relative time. 
+       _.fromNow(new Date(2010, 1, 1), new Date(2010, 1, 2)); // "about a day ago"
+       _.fromNow(new Date(2010, 1, 1, 0, 0, 0), new Date(2010, 1, 1, 0, 0, 30)); // "less than a minute ago"
+       _.fromNow(new Date(2010, 1, 1, 0, 0, 30), new Date(2010, 1, 1, 0, 0, 0)); // "in less than a minute"
 
-The base strings can be customized with `_.customizedate()`.
+_.isLeapYear(dateInputOrYear) `:Boolean`
+----------------------------------------
 
-Examples:
+Returns `true` if the year is a leap year, `false` if it is not
+
+You can pass any value specified by the dateInput formats above, *OR* you can pass a number less than 10,000 to check a specific year without converting to a `Date`.
+
+Examples :
+
+    _.isLeapYear(2000) // true
+    _.isLeapYear(2001) // false
+    _.isLeapYear([2100, 0, 1]) // false
 
-    _.relativetime(1000 * 30); // "less than a minute"
-       _.relativetime(1000 * 60); // "about a minute"
-       _.relativetime(1000 * 60 * 5); // "5 minutes"
-       _.relativetime(1000 * 60 * 60); // "about an hour"
-       _.relativetime(1000 * 60 * 60 * 5); // "about 5 hours"
-       _.relativetime(1000 * 60 * 60 * 24); // "a day"
-       _.relativetime(1000 * 60 * 60 * 24 * 5); // "5 days"
-       _.relativetime(1000 * 60 * 60 * 24 * 30); // "about a month"
-       _.relativetime(1000 * 60 * 60 * 24 * 30 * 5); // "5 months"
-       _.relativetime(1000 * 60 * 60 * 24 * 30 * 12); // "about a year"
-       _.relativetime(1000 * 60 * 60 * 24 * 365 * 5); // "5 years"
+_.msApart(dateInput1, [dateInput2]) `:Number`
+---------------------------------------------
 
-_.msapart(time1, [time 2])
---------------------------
+Returns the number of milliseconds between `dateInput1` and `dateInput2`. If `dateInput1` is before `dateInput2`, it will return a negative value.
 
-Returns the number of milliseconds between time1 and time2. If time1 is before time2, it will return a negative value.
+`dateInput2` is optional, and if left out will default to _.now(true).
 
-`time1` and `time2` can be a Date or a number of milliseconds. They can be mixed and matched as well (`time1` = Date, `time2` = milliseconds)
+_.now(asTimestamp) `:Date`
+-------------------------
 
-`time2` is optional, and if left out will default to _.now(true).
+Returns the current date. 
+
+Pass `true` to return a UNIX timestamp, otherwise it will return a `Date` object.
 
-_.fromnow(time1, [time 2])
-----------------------
+_.relativeTime(dateInput) `:String`
+-----------------------------------
 
-Returns a string as time from now. Parameters behave the same way as _.msapart().
+Returns a string as relative time. 
 
 The base strings can be customized with `_.customizedate()`.
 
 Examples:
 
-       _.fromnow(30 * 1000, 0); // "in less than a minute"
-       _.fromnow(0, 30 * 1000); // "less than a minute ago"
+    _.relativeTime(1000 * 30); // "less than a minute"
+       _.relativeTime(1000 * 60); // "about a minute"
+       _.relativeTime(1000 * 60 * 5); // "5 minutes"
+       _.relativeTime(1000 * 60 * 60); // "about an hour"
+       _.relativeTime(1000 * 60 * 60 * 5); // "about 5 hours"
+       _.relativeTime(1000 * 60 * 60 * 24); // "a day"
+       _.relativeTime(1000 * 60 * 60 * 24 * 5); // "5 days"
+       _.relativeTime(1000 * 60 * 60 * 24 * 30); // "about a month"
+       _.relativeTime(1000 * 60 * 60 * 24 * 30 * 5); // "5 months"
+       _.relativeTime(1000 * 60 * 60 * 24 * 30 * 12); // "about a year"
+       _.relativeTime(1000 * 60 * 60 * 24 * 365 * 5); // "5 years"
+
+_.subtractTime(dateInput1, timeToSubtract) `:Date`
+--------------------------------------------------
+
+Functions the same as `_.addTime()`, only using subtraction instead of addition.
+
+Example:
     
-_.customizedate(object)
+    _.date([2010, 1, 28]) // February 28
+    _.subtractTime([2010, 1, 28], {M:1}) // January 28
+118N and Customization
+======================
+
+To customize the wording of `_.formatDate()`, `_.relativeTime()`, and `_.fromNow()`, you can use the `_.customizeDate()` function, passing in an 
+object with the parameters you wish to overwrite.
+    
+_.customizeDate(object)
 -----------------------
 
-To customize the wording, you can use the **_.customizedate** function, passing in an 
-object with the paremeters you wish to overwrite.
-
-    _.customizedate({
+    _.customizeDate({
         weekdays:["Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"],
+        weekdaysShort:["Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"],
         months:["January", "February", "March", "April", "May", "June", "July", 
             "August", "September", "October", "November", "December"],
+        monthsShort:["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"],
         ordinal:function(number){
             return (Math.floor(number / 10) === 1) ? 'th' :
                                (number % 10 === 1) ? 'st' :
                                (number % 10 === 2) ? 'nd' :
                                (number % 10 === 3) ? 'rd' : 'th';
         },
-               timeago = {
+               timeago : {
                        future: "in %s",
                        past: "%s ago",
             ss: "less than a minute",
@@ -268,10 +383,18 @@ object with the paremeters you wish to overwrite.
     ["Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"]
 An array of day names, starting with Sunday. 
 
+### weekdaysShort
+    ["Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"]
+An array of abbreviated day names, starting with Sunday. 
+
 ### months
     ["January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"]
 An array of the names of the months, starting with January.
 
+### monthsShort
+    ["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"]
+An array of the abbreviated names of the months, starting with January.
+
 ### ordinal
     function(number){
         return (Math.floor(number / 10) === 1) ? 'th' :
@@ -300,14 +423,22 @@ A function that returns a string to be appended to the number passed in.
         yy: "%d years"
     }
 
-The strings used in _.fromnow() and _.relativetime().
+The strings used in `_.fromNow()` and `_.relativeTime()`.
 
-`future` and `past` are used in _.fromnow(), the rest are used in _.relativetime().
+`future` and `past` are used in _.fromNow(), the rest are used in _.relativeTime().
 
-For the values for _.relativetime(), a lowercase character refers to the singular, and an uppercase character refers to the plural.
+For the values for _.relativeTime(), a lowercase character refers to the singular, and an uppercase character refers to the plural.
 
-Thanks
-------
+Tests
+-----
+
+### Speed tests
+[Floor vs bitwiseor vs parseint](http://jsperf.com/floor-vs-bitwise-or-vs-parseint)
+[Switch/case vs object of functions lookup](http://jsperf.com/object-of-functions-vs-switch)
+[Left zero filling](http://jsperf.com/left-zero-filling)
+
+Thanks to...
+------------
 
 The folks over at [date.js](http://code.google.com/p/datejs/).
 
@@ -316,6 +447,11 @@ The folks over at [date.js](http://code.google.com/p/datejs/).
 Changelog
 ---------
 
+### 0.3.0
+
+Switched to the Underscore methodology of not mucking with the native objects' prototypes.
+Made chaining possible.
+
 ### 0.2.1
 
 Changed date names to be a more pseudo standardized 'dddd, MMMM Do YYYY, h:mm:ss a'.
index b25638c074f503ead4cf949688bd1a1d779619c8..2d873a96946140c5864c0cf88b65046b9ce9b925 100644 (file)
@@ -39,6 +39,7 @@
         };
         
     // left zero fill a number
+    // see http://jsperf.com/left-zero-filling for performance comparison
     function leftZeroFill(number, targetLength) {
         var output = number + '';
         while (output.length < targetLength) {
                 charactersToReplace = /(\\)?(Mo|MM?M?M?|Do|DDDo|DD?D?D?|dddd?|do?|w[o|w]?|YYYY|YY|a|A|hh?|HH?|mm?|ss?)/g;
             // check if the character is a format
             // return formatted string or non string.
+            //
+            // uses switch/case instead of an object of named functions (like http://phpjs.org/functions/date:380) 
+            // for minification and performance
+            // see http://jsperf.com/object-of-functions-vs-switch for performance comparison
             function replaceFunction(input) {
                 // create a couple variables to be used later inside one of the cases.
                 var a, b;
index 617387d4c3eb1287824d715c98a0f2024c49244c..929566dd8691e6fc0b54bc69223ccd3a00736d2d 100644 (file)
@@ -5,4 +5,4 @@
 //
 // Version 0.3.0
 
-(function(a,b,c){function m(a,b){return h[a].replace(/%d/i,b||1)}function l(b){return b===c?e.now(!0):b instanceof a?b.getTime():b}function k(b){function q(a){return p[a]?p[a]():a}var c=this,d=c.getMonth(),e=c.getDate(),h=c.getFullYear(),k=c.getDay(),l=c.getHours(),m=c.getMinutes(),n=c.getSeconds(),o=/Mo|MM?M?M?|Do|DDDo|DD?D?D?|dddd?|do?|w[o|w]?|YYYY|YY|a|A|hh?|HH?|mm?|ss?/g,p={M:function(){return d+1},Mo:function(){return d+1+i(d+1)},MM:function(){return j(d+1,2)},MMM:function(){return f[d].slice(0,3)},MMMM:function(){return f[d]},D:function(){return e},Do:function(){return e+i(e)},DD:function(){return j(e,2)},DDD:function(){var b=new a(h,d,e),c=new a(h,0,1);return(b-c)/864e5+1.5|0},DDDo:function(){var a=p.DDD();return a+i(a)},DDDD:function(){return j(p.DDD(),3)},d:function(){return k},"do":function(){return k+i(k)},ddd:function(){return g[k].slice(0,3)},dddd:function(){return g[k]},w:function(){var b=new a(h,d,e-k+5),c=new a(b.getFullYear(),0,4);return(b-c)/864e5/7+1.5|0},wo:function(){var a=p.w();return a+i(a)},ww:function(){return j(p.w(),2)},YY:function(){return(h+"").slice(-2)},YYYY:function(a){return h},a:function(){return l>11?"pm":"am"},A:function(){return l>11?"PM":"AM"},H:function(){return l},HH:function(){return j(l,2)},h:function(){return l%12||12},hh:function(){return j(l%12||12,2)},m:function(){return m},mm:function(){return j(m,2)},s:function(){return n},ss:function(){return j(n,2)}};return b.replace(o,q)}function j(a,b){var c=a+"";while(c.length<b)c="0"+c;return c}function i(a){return(a/10|0)===1?"th":a%10===1?"st":a%10===2?"nd":a%10===3?"rd":"th"}var d=this,e,f=["January","February","March","April","May","June","July","August","September","October","November","December"],g=["Sunday","Monday","Tuesday","Wednesday","Thursday","Friday","Saturday"],h={future:"in %s",past:"%s ago",s:"less than a minute",m:"about a minute",mm:"%d minutes",h:"about an hour",hh:"about %d hours",d:"a day",dd:"%d days",M:"about a month",MM:"%d months",y:"about a year",yy:"%d years"};e={now:function(b){return b?(new a).getTime():new a},relativetime:function(a){var b=Math.abs(l(a))/1e3,c=b/60,d=c/60,e=d/24,f=e/365;return b<45&&m("s",b|0)||b<90&&m("m")||c<45&&m("mm",c|0)||c<90&&m("h")||d<24&&m("hh",d|0)||d<48&&m("d")||e<30&&m("dd",e|0)||e<60&&m("M")||e<350&&m("MM",e/30|0)||f<2&&m("y")||m("yy",f|0)},msapart:function(a,b){return l(a)-l(b)},fromnow:function(a,b){var c=e.msapart(a,b),d=c<0?h.past:h.future;return d.replace(/%s/i,e.relativetime(c))},customizedate:function(a){a.weekdays&&b.isArray(a.weekdays)&&a.weekdays.length===7&&(g=a.weekdays),a.months&&b.isArray(a.months)&&a.months.length===12&&(f=a.months),a.timeago&&b.extend(h,a.timeago),a.ordinal&&b.isFunction(a.ordinal)&&(i=a.ordinal)}},a.prototype.humanize=k,d._d=e,b&&b.mixin&&b.mixin(e)})(Date,_)
+(function(a,b,c){function q(a,b){return j[a].replace(/%d/i,b||1)}function p(d){return d===c?e.now():b.isDate(d)?d:b.isArray(d)&&d.length>2?n(d):new a(d)}function o(d){return d===c?e.now(!0):isNaN(d)?b.isDate(d)?d.getTime():b.isArray(d)&&d.length>2?n(d).getTime():(new a(d)).getTime():d}function n(b){return new a(b[0],b[1]||0,b[2]||1,b[3]||0,b[4]||0,b[5]||0,b[6]||0)}function m(b,c,d){var e=(b.ms||b[6]||0)+(b.s||b[5]||0)*1e3+(b.m||b[4]||0)*6e4+(b.h||b[3]||0)*36e5+(b.d||b[2]||0)*864e5+(b.w||0)*6048e5,f=(b.M||b[1]||0)+(b.y||b[0]||0)*12,g;e&&c.setMilliseconds(c.getMilliseconds()+e*d),f&&(g=c.getDate(),c.setDate(1),c.setMonth(c.getMonth()+f*d),c.setDate(Math.min((new a(c.getFullYear(),c.getMonth()+1,0)).getDate(),g)));return c}function l(a,b){var c=a+"";while(c.length<b)c="0"+c;return c}var d=this,e,f=["January","February","March","April","May","June","July","August","September","October","November","December"],g=["Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec"],h=["Sunday","Monday","Tuesday","Wednesday","Thursday","Friday","Saturday"],i=["Sun","Mon","Tue","Wed","Thu","Fri","Sat"],j={future:"in %s",past:"%s ago",s:"less than a minute",m:"about a minute",mm:"%d minutes",h:"about an hour",hh:"about %d hours",d:"a day",dd:"%d days",M:"about a month",MM:"%d months",y:"about a year",yy:"%d years"},k=function(a){var b=a%10;return(a%100/10|0)===1?"th":b===1?"st":b===2?"nd":b===3?"rd":"th"};e={addTime:function(a,b){return m(b,p(a),1)},customizeDate:function(a){var c=a.weekdays,d=a.weekdaysShort,e=a.months,l=a.monthsShort,m=a.relativeTime,n=a.ordinal;c&&b.isArray(c)&&c.length===7&&(h=c),d&&b.isArray(d)&&d.length===7&&(i=d),e&&b.isArray(e)&&e.length===12&&(f=e),l&&b.isArray(l)&&l.length===12&&(g=l),m&&b.extend(j,m),n&&b.isFunction(n)&&(k=n)},date:function(a){return p(a)},formatDate:function(b,c){function t(b){var c,d;switch(b){case"M":return e+1;case"Mo":return e+1+k(e+1);case"MM":return l(e+1,2);case"MMM":return g[e];case"MMMM":return f[e];case"D":return j;case"Do":return j+k(j);case"DD":return l(j,2);case"DDD":c=new a(m,e,j),d=new a(m,0,1);return(c-d)/864e5+1.5|0;case"DDDo":c=t("DDD");return c+k(c);case"DDDD":return l(t("DDD"),3);case"d":return n;case"do":return n+k(n);case"ddd":return i[n];case"dddd":return h[n];case"w":c=new a(m,e,j-n+5),d=new a(c.getFullYear(),0,4);return(c-d)/864e5/7+1.5|0;case"wo":c=t("w");return c+k(c);case"ww":return l(t("w"),2);case"YY":return(m+"").slice(-2);case"YYYY":return m;case"a":return o>11?"pm":"am";case"A":return o>11?"PM":"AM";case"H":return o;case"HH":return l(o,2);case"h":return o%12||12;case"hh":return l(o%12||12,2);case"m":return q;case"mm":return l(q,2);case"s":return r;case"ss":return l(r,2);default:return b.replace("\\","")}}var d=p(b),e=d.getMonth(),j=d.getDate(),m=d.getFullYear(),n=d.getDay(),o=d.getHours(),q=d.getMinutes(),r=d.getSeconds(),s=/(\\)?(Mo|MM?M?M?|Do|DDDo|DD?D?D?|dddd?|do?|w[o|w]?|YYYY|YY|a|A|hh?|HH?|mm?|ss?)/g;return c.replace(s,t)},fromNow:function(a,b){var c=e.msApart(a,b),d=c<0?j.past:j.future;return d.replace(/%s/i,e.relativeTime(c))},isLeapYear:function(a){var b=!isNaN(a)&&a<1e4?a:p(a).getFullYear();return b%4===0&&b%100!==0||b%400===0},msApart:function(a,b){return o(a)-o(b)},now:function(b){return b?(new a).getTime():new a},relativeTime:function(a){var b=Math.abs(o(a))/1e3,c=b/60,d=c/60,e=d/24,f=e/365;return b<45&&q("s",b|0)||b<90&&q("m")||c<45&&q("mm",c|0)||c<90&&q("h")||d<24&&q("hh",d|0)||d<48&&q("d")||e<30&&q("dd",e|0)||e<60&&q("M")||e<350&&q("MM",e/30|0)||f<2&&q("y")||q("yy",f|0)},subtractTime:function(a,b){return m(b,p(a),-1)}},b&&b.mixin&&b.mixin(e)})(Date,_)