├── .babelrc ├── .flowconfig ├── .gitignore ├── .travis.yml ├── FORMATTING.md ├── LICENSE ├── README.md ├── bower.json ├── easy-date-light.js ├── easy-date-light.min.js ├── easy-date.js ├── easy-date.min.js ├── package.json ├── src ├── .keep ├── bundled.js ├── date-format.js └── easy-date.js ├── test ├── .keep ├── dateLegacySpec.js ├── dateSpec.js ├── easyDateClassSpec.js ├── easyDateFormatsLegacySpec.js ├── easyDateFormatsSpec.js ├── easyDateLegacySpec.js ├── easyDateSpec.js └── index.html ├── webpack.config.dev.js ├── webpack.config.js ├── webpack.config.prod.js └── yarn.lock /.babelrc: -------------------------------------------------------------------------------- 1 | { 2 | "plugins": ["transform-class-properties"], 3 | "presets" : [ 4 | "flow", 5 | "env" 6 | ] 7 | } 8 | -------------------------------------------------------------------------------- /.flowconfig: -------------------------------------------------------------------------------- 1 | [ignore] 2 | 3 | [include] 4 | 5 | [libs] 6 | 7 | [lints] 8 | 9 | [options] 10 | 11 | [strict] 12 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Logs 2 | logs 3 | *.log 4 | 5 | # Runtime data 6 | pids 7 | *.pid 8 | *.seed 9 | 10 | # Directory for instrumented libs generated by jscoverage/JSCover 11 | lib-cov 12 | 13 | # Coverage directory used by tools like istanbul 14 | coverage 15 | 16 | # Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files) 17 | .grunt 18 | 19 | # node-waf configuration 20 | .lock-wscript 21 | 22 | # Compiled binary addons (http://nodejs.org/api/addons.html) 23 | build/Release 24 | 25 | # Dependency directory 26 | # https://www.npmjs.org/doc/misc/npm-faq.html#should-i-check-my-node_modules-folder-into-git 27 | node_modules 28 | *.orig 29 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | language: node_js 2 | node_js: 3 | - v7.10.0 4 | -------------------------------------------------------------------------------- /FORMATTING.md: -------------------------------------------------------------------------------- 1 | | Mask | Description | 2 | | --- | --- | 3 | | `d` | Day of the month as digits; no leading zero for single-digit days. | 4 | | `dd` | Day of the month as digits; leading zero for single-digit days. | 5 | | `ddd` | Day of the week as a three-letter abbreviation. | 6 | | `dddd` | Day of the week as its full name. | 7 | | `m` | Month as digits; no leading zero for single-digit months. | 8 | | `mm` | Month as digits; leading zero for single-digit months. | 9 | | `mmm` | Month as a three-letter abbreviation. | 10 | | `mmmm` | Month as its full name. | 11 | | `yy` | Year as last two digits; leading zero for years less than 10. | 12 | | `yyyy` | Year represented by four digits. | 13 | | `h` | Hours; no leading zero for single-digit hours (12-hour clock). | 14 | | `hh` | Hours; leading zero for single-digit hours (12-hour clock). | 15 | | `H` | Hours; no leading zero for single-digit hours (24-hour clock). | 16 | | `HH` | Hours; leading zero for single-digit hours (24-hour clock). | 17 | | `M` | Minutes; no leading zero for single-digit minutes. Uppercase M unlike CF `timeFormat`'s m to avoid conflict with months. | 18 | | `MM` | Minutes; leading zero for single-digit minutes. Uppercase MM unlike CF `timeFormat`'s mm to avoid conflict with months. | 19 | | `s` | Seconds; no leading zero for single-digit seconds. | 20 | | `ss` | Seconds; leading zero for single-digit seconds. | 21 | | `l` _or_ `L` | Milliseconds. `l` gives 3 digits. `L` gives 2 digits. | 22 | | `t` | Lowercase, single-character time marker string: _a_ or _p_. | 23 | | `tt` | Lowercase, two-character time marker string: _am_ or _pm_. | 24 | | `T` | Uppercase, single-character time marker string: _A_ or _P_. Uppercase T unlike CF's t to allow for user-specified casing. | 25 | | `TT` | Uppercase, two-character time marker string: _AM_ or _PM_. Uppercase TT unlike CF's tt to allow for user-specified casing. | 26 | | `Z` | US timezone abbreviation, e.g. _EST_ or _MDT_. With non-US timezones or in the Opera browser, the GMT/UTC offset is returned, e.g. _GMT-0500_ | 27 | | `o` | GMT/UTC timezone offset, e.g. _-0500_ or _+0230_. | 28 | | `S` | The date's ordinal suffix (_st_, _nd_, _rd_, or _th_). Works well with `d`. | 29 | | `'…'` _or_ `"…"` | Literal character sequence. Surrounding quotes are removed. | 30 | | `UTC:` | Must be the first four characters of the mask. Converts the date from local time to UTC/GMT/Zulu time before applying the mask. The "UTC:" prefix is removed. | 31 | 32 | 33 | 34 | | Name | Mask | Example | 35 | | --- | --- | --- | 36 | | default | ddd mmm dd yyyy HH:MM:ss | Sat Jun 09 2007 17:46:21 | 37 | | shortDate | m/d/yy | 6/9/07 | 38 | | mediumDate | mmm d, yyyy | Jun 9, 2007 | 39 | | longDate | mmmm d, yyyy | June 9, 2007 | 40 | | fullDate | dddd, mmmm d, yyyy | Saturday, June 9, 2007 | 41 | | shortTime | h:MM TT | 5:46 PM | 42 | | mediumTime | h:MM:ss TT | 5:46:21 PM | 43 | | longTime | h:MM:ss TT Z | 5:46:21 PM EST | 44 | | isoDate | yyyy-mm-dd | 2007-06-09 | 45 | | isoTime | HH:MM:ss | 17:46:21 | 46 | | isoDateTime | yyyy-mm-dd'T'HH:MM:ss | 2007-06-09T17:46:21 | 47 | | isoUtcDateTime | UTC:yyyy-mm-dd'T'HH:MM:ss'Z' | 2007-06-09T22:46:21Z | 48 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2015 Melvin Sembrano 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | 23 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | [![Build Status](https://travis-ci.org/melvinsembrano/easy-date.svg?branch=master)](https://travis-ci.org/melvinsembrano/easy-date) 2 | [![npm version](https://badge.fury.io/js/easy-date.svg)](https://badge.fury.io/js/easy-date) 3 | # EasyDate 4 | EasyDate is a Javascript extension for easy dates manipulations which was 5 | heavily inspired by Rails ActiveSupport::Duration class. 6 | 7 | ### Installation 8 | **Node.js** `npm install easy-date` 9 | 10 | **Bower** `bower install easy-date` 11 | 12 | [**Download the latest**](https://github.com/melvinsembrano/easy-date/archive/master.zip) 13 | 14 | ### Usage 15 | 16 | ``` 17 | var easyDate = require('easy-date').easyDate; 18 | // or 19 | import { easyDate, backwardCompatibility } from 'easy-date' 20 | 21 | // this will expose the number extension methods 22 | // which was a default before version 1.2 23 | backwardCompatibility(); 24 | 25 | ``` 26 | **Basic usage:** 27 | 28 | ``` 29 | import { easyDate } from 'easy-date'; 30 | 31 | let date1 = easyDate(3).days().ago(); 32 | const date2 = easyDate(10).months().fromNow(); 33 | const date3 = easyDate(5).years().ago(); 34 | const date4 = easyDate(10).days().since(date2); 35 | const date5 = easyDate(1).year().before(date1); 36 | var yesterday = easyDate(24).hours().ago(); 37 | 38 | ``` 39 | **Legacy syntax usage:** 40 | 41 | ``` 42 | import { backwardCompatibility } from 'easy-date'; 43 | backwardCompatibility(); 44 | ``` 45 | 46 | by adding the codes above, new methods are now available on all numbers: 47 | * day(), days() 48 | * month(), months() 49 | * year(), years() 50 | * hour(), hours() 51 | ``` 52 | var date1 = 3..days().fromNow(); 53 | var date2 = (10).months().ago(); 54 | 55 | var yesterday = 1..day().ago(); 56 | var today = new Date(); 57 | var num = 5; 58 | num.years().before(today); //==> is equal to 5..years().ago() 59 | num.years().since(today); //==> is equal to 5..years().fromNow() 60 | 61 | ``` 62 | 63 | it will also add some basic date helpers 64 | ``` 65 | Date.today() //=> new Date() 66 | Date.yesterday() //=> 1..day().ago() 67 | Date.tommorrow() //=> 1..day().fromNow() 68 | ``` 69 | 70 | #### Formatting 71 | The date.format library written by Steven Levithan (http://blog.stevenlevithan.com/archives/date-time-format) is now integrated for a very nice date formatting. 72 | 73 | ``` 74 | 5..days().fromNow().format("d mmmm yyyy"); 75 | // is same as 76 | 5..days().fromNow("d mmmm yyyy"); 77 | 78 | // other functions 79 | Date.today("yyyy-mm-dd"); 80 | Date.yesterday("dddd"); 81 | 3..days().since(Date.yesterday(), "mmm dd, yyyy"); 82 | ``` 83 | 84 | [Check the complete formatting here](FORMATTING.md) 85 | 86 | #### Contributing to easy-date 87 | 88 | * Check out the latest master to make sure the feature hasn't been implemented or the bug hasn't been fixed yet. 89 | * Check out the issue tracker to make sure someone already hasn't requested it and/or contributed it. 90 | * Fork the project. 91 | * Start a feature/bugfix branch. 92 | * Commit and push until you are happy with your contribution. 93 | * Make sure to add tests for it. This is important so I don't break it in a future version unintentionally. 94 | * Please try not to mess with the webpack.config.js, package.json, version, or history. If you want to have your own version, or is otherwise necessary, that is fine, but please isolate to its own commit so I can cherry-pick around it. 95 | * Checkout package.json, there are few scripts that are very helpful during development. 96 | 97 | ##### Copyright 98 | Copyright (c) 2017 Melvin Sembrano. See [LICENSE](LICENSE) for further details 99 | -------------------------------------------------------------------------------- /bower.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "easy-date", 3 | "main": "easy-date.js", 4 | "version": "1.1.3", 5 | "homepage": "https://github.com/melvinsembrano/easy-date", 6 | "authors": [ 7 | "Melvin Sembrano " 8 | ], 9 | "description": "EasyDate is a Javascript extension for easy dates manipulations which is heavily inspired by Rails ActiveSupport::Duration class.", 10 | 11 | "keywords": [ 12 | "EasyDate", 13 | "Date", 14 | "Javascript Date", 15 | "format", 16 | "date format", 17 | "javascript date format" 18 | ], 19 | "license": "MIT", 20 | "ignore": [ 21 | "**/.*", 22 | "node_modules", 23 | "bower_components", 24 | "test", 25 | "tests", 26 | "src", 27 | "karma.conf.js", 28 | "Gruntfile.coffee", 29 | "package.json", 30 | "bower.json", 31 | "webpack.config*", 32 | "yarn.lock" 33 | ] 34 | } 35 | -------------------------------------------------------------------------------- /easy-date-light.js: -------------------------------------------------------------------------------- 1 | (function webpackUniversalModuleDefinition(root, factory) { 2 | if(typeof exports === 'object' && typeof module === 'object') 3 | module.exports = factory(); 4 | else if(typeof define === 'function' && define.amd) 5 | define([], factory); 6 | else { 7 | var a = factory(); 8 | for(var i in a) (typeof exports === 'object' ? exports : root)[i] = a[i]; 9 | } 10 | })(window, function() { 11 | return /******/ (function(modules) { // webpackBootstrap 12 | /******/ // The module cache 13 | /******/ var installedModules = {}; 14 | /******/ 15 | /******/ // The require function 16 | /******/ function __webpack_require__(moduleId) { 17 | /******/ 18 | /******/ // Check if module is in cache 19 | /******/ if(installedModules[moduleId]) { 20 | /******/ return installedModules[moduleId].exports; 21 | /******/ } 22 | /******/ // Create a new module (and put it into the cache) 23 | /******/ var module = installedModules[moduleId] = { 24 | /******/ i: moduleId, 25 | /******/ l: false, 26 | /******/ exports: {} 27 | /******/ }; 28 | /******/ 29 | /******/ // Execute the module function 30 | /******/ modules[moduleId].call(module.exports, module, module.exports, __webpack_require__); 31 | /******/ 32 | /******/ // Flag the module as loaded 33 | /******/ module.l = true; 34 | /******/ 35 | /******/ // Return the exports of the module 36 | /******/ return module.exports; 37 | /******/ } 38 | /******/ 39 | /******/ 40 | /******/ // expose the modules object (__webpack_modules__) 41 | /******/ __webpack_require__.m = modules; 42 | /******/ 43 | /******/ // expose the module cache 44 | /******/ __webpack_require__.c = installedModules; 45 | /******/ 46 | /******/ // define getter function for harmony exports 47 | /******/ __webpack_require__.d = function(exports, name, getter) { 48 | /******/ if(!__webpack_require__.o(exports, name)) { 49 | /******/ Object.defineProperty(exports, name, { enumerable: true, get: getter }); 50 | /******/ } 51 | /******/ }; 52 | /******/ 53 | /******/ // define __esModule on exports 54 | /******/ __webpack_require__.r = function(exports) { 55 | /******/ if(typeof Symbol !== 'undefined' && Symbol.toStringTag) { 56 | /******/ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' }); 57 | /******/ } 58 | /******/ Object.defineProperty(exports, '__esModule', { value: true }); 59 | /******/ }; 60 | /******/ 61 | /******/ // create a fake namespace object 62 | /******/ // mode & 1: value is a module id, require it 63 | /******/ // mode & 2: merge all properties of value into the ns 64 | /******/ // mode & 4: return value when already ns object 65 | /******/ // mode & 8|1: behave like require 66 | /******/ __webpack_require__.t = function(value, mode) { 67 | /******/ if(mode & 1) value = __webpack_require__(value); 68 | /******/ if(mode & 8) return value; 69 | /******/ if((mode & 4) && typeof value === 'object' && value && value.__esModule) return value; 70 | /******/ var ns = Object.create(null); 71 | /******/ __webpack_require__.r(ns); 72 | /******/ Object.defineProperty(ns, 'default', { enumerable: true, value: value }); 73 | /******/ if(mode & 2 && typeof value != 'string') for(var key in value) __webpack_require__.d(ns, key, function(key) { return value[key]; }.bind(null, key)); 74 | /******/ return ns; 75 | /******/ }; 76 | /******/ 77 | /******/ // getDefaultExport function for compatibility with non-harmony modules 78 | /******/ __webpack_require__.n = function(module) { 79 | /******/ var getter = module && module.__esModule ? 80 | /******/ function getDefault() { return module['default']; } : 81 | /******/ function getModuleExports() { return module; }; 82 | /******/ __webpack_require__.d(getter, 'a', getter); 83 | /******/ return getter; 84 | /******/ }; 85 | /******/ 86 | /******/ // Object.prototype.hasOwnProperty.call 87 | /******/ __webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); }; 88 | /******/ 89 | /******/ // __webpack_public_path__ 90 | /******/ __webpack_require__.p = ""; 91 | /******/ 92 | /******/ 93 | /******/ // Load entry module and return exports 94 | /******/ return __webpack_require__(__webpack_require__.s = 0); 95 | /******/ }) 96 | /************************************************************************/ 97 | /******/ ({ 98 | 99 | /***/ "./src/date-format.js": 100 | /*!****************************!*\ 101 | !*** ./src/date-format.js ***! 102 | \****************************/ 103 | /*! no static exports found */ 104 | /***/ (function(module, exports, __webpack_require__) { 105 | 106 | "use strict"; 107 | eval("\n\nObject.defineProperty(exports, \"__esModule\", {\n value: true\n});\n/*\n * Date Format 1.2.3\n * (c) 2007-2009 Steven Levithan \n * MIT license\n *\n * Includes enhancements by Scott Trenda \n * and Kris Kowal \n *\n * Accepts a date, a mask, or a date and a mask.\n * Returns a formatted version of the given date.\n * The date defaults to the current date/time.\n * The mask defaults to dateFormat.masks.default.\n */\n\nvar dateFormat = function () {\n var token = /d{1,4}|m{1,4}|yy(?:yy)?|([HhMsTt])\\1?|[LloSZ]|\"[^\"]*\"|'[^']*'/g;\n var timezone = /\\b(?:[PMCEA][SDP]T|(?:Pacific|Mountain|Central|Eastern|Atlantic) (?:Standard|Daylight|Prevailing) Time|(?:GMT|UTC)(?:[-+]\\d{4})?)\\b/g;\n var timezoneClip = /[^-+\\dA-Z]/g;\n\n var pad = function pad(val, len) {\n val = String(val);\n len = len || 2;\n while (val.length < len) {\n val = '0' + val;\n }\n return val;\n };\n\n // Regexes and supporting functions are cached through closure\n return function (date, mask, utc) {\n var dF = dateFormat;\n // You can't provide utc if you skip other args (use the \"UTC:\" mask prefix)\n if (arguments.length === 1 && Object.prototype.toString.call(date) === '[object String]' && !/\\d/.test(date)) {\n mask = date;\n date = undefined;\n }\n // Passing date through Date applies Date.parse, if necessary\n date = date ? new Date(date) : new Date();\n if (isNaN(date)) {\n throw SyntaxError('invalid date');\n }\n mask = String(dF.masks[mask] || mask || dF.masks['default']);\n // Allow setting the utc argument via the mask\n if (mask.slice(0, 4) === 'UTC:') {\n mask = mask.slice(4);\n utc = true;\n }\n var _ = utc ? 'getUTC' : 'get';\n var d = date[_ + 'Date']();\n var D = date[_ + 'Day']();\n var m = date[_ + 'Month']();\n var y = date[_ + 'FullYear']();\n var H = date[_ + 'Hours']();\n var M = date[_ + 'Minutes']();\n var s = date[_ + 'Seconds']();\n var L = date[_ + 'Milliseconds']();\n var o = utc ? 0 : date.getTimezoneOffset();\n var flags = {\n d: d,\n dd: pad(d),\n ddd: dF.i18n.dayNames[D],\n dddd: dF.i18n.dayNames[D + 7],\n m: m + 1,\n mm: pad(m + 1),\n mmm: dF.i18n.monthNames[m],\n mmmm: dF.i18n.monthNames[m + 12],\n yy: String(y).slice(2),\n yyyy: y,\n h: H % 12 || 12,\n hh: pad(H % 12 || 12),\n H: H,\n HH: pad(H),\n M: M,\n MM: pad(M),\n s: s,\n ss: pad(s),\n l: pad(L, 3),\n L: pad(L > 99 ? Math.round(L / 10) : L),\n t: H < 12 ? 'a' : 'p',\n tt: H < 12 ? 'am' : 'pm',\n T: H < 12 ? 'A' : 'P',\n TT: H < 12 ? 'AM' : 'PM',\n Z: utc ? 'UTC' : (String(date).match(timezone) || ['']).pop().replace(timezoneClip, ''),\n o: (o > 0 ? '-' : '+') + pad(Math.floor(Math.abs(o) / 60) * 100 + Math.abs(o) % 60, 4),\n S: ['th', 'st', 'nd', 'rd'][d % 10 > 3 ? 0 : (d % 100 - d % 10 !== 10) * d % 10]\n };\n return mask.replace(token, function ($0) {\n if ($0 in flags) {\n return flags[$0];\n } else {\n return $0.slice(1, $0.length - 1);\n }\n });\n };\n}();\n// Some common format strings\ndateFormat.masks = {\n 'default': 'ddd mmm dd yyyy HH:MM:ss',\n shortDate: 'm/d/yy',\n mediumDate: 'mmm d, yyyy',\n longDate: 'mmmm d, yyyy',\n fullDate: 'dddd, mmmm d, yyyy',\n shortTime: 'h:MM TT',\n mediumTime: 'h:MM:ss TT',\n longTime: 'h:MM:ss TT Z',\n isoDate: 'yyyy-mm-dd',\n isoTime: 'HH:MM:ss',\n isoDateTime: 'yyyy-mm-dd\\'T\\'HH:MM:ss',\n isoUtcDateTime: 'UTC:yyyy-mm-dd\\'T\\'HH:MM:ss\\'Z\\''\n};\n// Internationalization strings\ndateFormat.i18n = {\n dayNames: ['Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday'],\n monthNames: ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec', 'January', 'February', 'March', 'April', 'May', 'June', 'July', 'August', 'September', 'October', 'November', 'December']\n};\n\n// For convenience...\nif (Date.prototype.format === undefined) {\n Date.prototype.format = function (mask, utc) {\n return dateFormat(this, mask, utc);\n };\n}\n\nexports.default = dateFormat;\n\n//# sourceURL=webpack:///./src/date-format.js?"); 108 | 109 | /***/ }), 110 | 111 | /***/ "./src/easy-date.js": 112 | /*!**************************!*\ 113 | !*** ./src/easy-date.js ***! 114 | \**************************/ 115 | /*! no static exports found */ 116 | /***/ (function(module, exports, __webpack_require__) { 117 | 118 | "use strict"; 119 | eval("\n\nObject.defineProperty(exports, \"__esModule\", {\n value: true\n});\nexports.backwardCompatibility = exports.easyDate = exports.EasyDate = undefined;\n\nvar _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if (\"value\" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();\n\nvar _dateFormat = __webpack_require__(/*! ./date-format */ \"./src/date-format.js\");\n\nvar _dateFormat2 = _interopRequireDefault(_dateFormat);\n\nfunction _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }\n\nfunction _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError(\"Cannot call a class as a function\"); } }\n\nvar EasyDate = function () {\n function EasyDate(date) {\n _classCallCheck(this, EasyDate);\n\n if (typeof date === 'string') {\n this._date = new Date(date);\n } else {\n this._date = date;\n }\n }\n\n _createClass(EasyDate, [{\n key: \"getDate\",\n value: function getDate() {\n return this._date;\n }\n }, {\n key: \"format\",\n value: function format(mask) {\n return (0, _dateFormat2.default)(this._date, mask);\n }\n }], [{\n key: \"formatDate\",\n value: function formatDate(date, mask) {\n if (!!mask) {\n return (0, _dateFormat2.default)(date, mask);\n } else {\n return date;\n }\n }\n }, {\n key: \"today\",\n value: function today(mask) {\n return EasyDate.formatDate(new Date(), mask);\n }\n }, {\n key: \"yesterday\",\n value: function yesterday(mask) {\n return new EasyD(1, 'day').ago(mask);\n }\n }, {\n key: \"tomorrow\",\n value: function tomorrow(mask) {\n return new EasyD(1, 'day').fromNow(mask);\n }\n }]);\n\n return EasyDate;\n}();\n\nvar EasyD = function () {\n function EasyD(value, conversionType) {\n _classCallCheck(this, EasyD);\n\n _initialiseProps.call(this);\n\n this.value = parseInt(value);\n this.conversionType = conversionType;\n }\n\n _createClass(EasyD, [{\n key: \"fromNow\",\n value: function fromNow(mask) {\n var processor = this.process(mask);\n if (processor) {\n return processor.fromNow();\n } else {\n return \"Processor not found.\";\n }\n }\n }, {\n key: \"ago\",\n value: function ago(mask) {\n var processor = this.process(mask);\n if (processor) {\n return processor.ago();\n } else {\n return \"Processor not found.\";\n }\n }\n }, {\n key: \"since\",\n value: function since(date, mask) {\n this.now = new Date(date.valueOf());\n return this.fromNow(mask);\n }\n }, {\n key: \"until\",\n value: function until(date, mask) {\n this.now = new Date(date.valueOf());\n return this.ago(mask);\n }\n }, {\n key: \"before\",\n value: function before(date, mask) {\n return this.until(date, mask);\n }\n }, {\n key: \"toString\",\n value: function toString() {\n return this.value + \" \" + this.conversionType + (this.value > 1 ? 's' : '');\n }\n }, {\n key: \"process\",\n value: function process(mask) {\n var conversionType = this.conversionType,\n timeProcessor = this.timeProcessor;\n\n var now = this.now || new Date();\n return {\n minute: function minute() {\n return timeProcessor(now, now.setMinutes, now.getMinutes, mask);\n },\n hour: function hour() {\n return timeProcessor(now, now.setHours, now.getHours, mask);\n },\n day: function day() {\n return timeProcessor(now, now.setDate, now.getDate, mask);\n },\n week: function week() {\n return null;\n },\n month: function month() {\n return timeProcessor(now, now.setMonth, now.getMonth, mask);\n },\n year: function year() {\n return timeProcessor(now, now.setFullYear, now.getFullYear, mask);\n }\n }[conversionType]();\n }\n }]);\n\n return EasyD;\n}();\n\nvar _initialiseProps = function _initialiseProps() {\n var _this = this;\n\n this.timeProcessor = function (now, set, get, mask) {\n var value = _this.value;\n\n return {\n ago: function ago() {\n set.call(now, get.call(now) - value);\n return EasyDate.formatDate(now, mask);\n },\n fromNow: function fromNow() {\n set.call(now, get.call(now) + value);\n return EasyDate.formatDate(now, mask);\n }\n };\n };\n};\n\nfunction easyDate(value) {\n var days = function days() {\n return new EasyD(value, 'day');\n };\n\n var months = function months() {\n return new EasyD(value, 'month');\n };\n\n var years = function years() {\n return new EasyD(value, 'year');\n };\n\n var hours = function hours() {\n return new EasyD(value, 'hour');\n };\n\n var minutes = function minutes() {\n return new EasyD(value, 'minute');\n };\n\n return {\n minute: minutes,\n minutes: minutes,\n hour: hours,\n hours: hours,\n day: days,\n days: days,\n month: months,\n months: months,\n year: years,\n years: years\n };\n}\n\nfunction backwardCompatibility() {\n\n var days = function days() {\n return new EasyD(this, 'day');\n };\n\n var months = function months() {\n return new EasyD(this, 'month');\n };\n\n var years = function years() {\n return new EasyD(this, 'year');\n };\n\n var hours = function hours() {\n return new EasyD(this, 'hour');\n };\n\n var minutes = function minutes() {\n return new EasyD(this, 'minute');\n };\n\n // $FlowFixMe\n Number.prototype.day = days;\n // $FlowFixMe\n Number.prototype.days = days;\n // $FlowFixMe\n Number.prototype.month = months;\n // $FlowFixMe\n Number.prototype.months = months;\n // $FlowFixMe\n Number.prototype.years = years;\n // $FlowFixMe\n Number.prototype.year = years;\n // $FlowFixMe\n Number.prototype.hours = hours;\n // $FlowFixMe\n Number.prototype.hour = hours;\n // $FlowFixMe\n Number.prototype.minute = minutes;\n\n // $FlowFixMe\n Object.assign(Date, {\n today: function today(mask) {\n return EasyDate.today(mask);\n },\n yesterday: function yesterday(mask) {\n return EasyDate.yesterday(mask);\n },\n tomorrow: function tomorrow(mask) {\n return EasyDate.tomorrow(mask);\n },\n tommorrow: function tommorrow(mask) {\n return EasyDate.tomorrow(mask);\n }\n });\n}\n\nexports.EasyDate = EasyDate;\nexports.easyDate = easyDate;\nexports.backwardCompatibility = backwardCompatibility;\n\n//# sourceURL=webpack:///./src/easy-date.js?"); 120 | 121 | /***/ }), 122 | 123 | /***/ 0: 124 | /*!********************************!*\ 125 | !*** multi ./src/easy-date.js ***! 126 | \********************************/ 127 | /*! no static exports found */ 128 | /***/ (function(module, exports, __webpack_require__) { 129 | 130 | eval("module.exports = __webpack_require__(/*! ./src/easy-date.js */\"./src/easy-date.js\");\n\n\n//# sourceURL=webpack:///multi_./src/easy-date.js?"); 131 | 132 | /***/ }) 133 | 134 | /******/ }); 135 | }); -------------------------------------------------------------------------------- /easy-date-light.min.js: -------------------------------------------------------------------------------- 1 | !function(e,t){if("object"==typeof exports&&"object"==typeof module)module.exports=t();else if("function"==typeof define&&define.amd)define([],t);else{var n=t();for(var r in n)("object"==typeof exports?exports:e)[r]=n[r]}}(window,function(){return function(e){var t={};function n(r){if(t[r])return t[r].exports;var o=t[r]={i:r,l:!1,exports:{}};return e[r].call(o.exports,o,o.exports,n),o.l=!0,o.exports}return n.m=e,n.c=t,n.d=function(e,t,r){n.o(e,t)||Object.defineProperty(e,t,{enumerable:!0,get:r})},n.r=function(e){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},n.t=function(e,t){if(1&t&&(e=n(e)),8&t)return e;if(4&t&&"object"==typeof e&&e&&e.__esModule)return e;var r=Object.create(null);if(n.r(r),Object.defineProperty(r,"default",{enumerable:!0,value:e}),2&t&&"string"!=typeof e)for(var o in e)n.d(r,o,function(t){return e[t]}.bind(null,o));return r},n.n=function(e){var t=e&&e.__esModule?function(){return e.default}:function(){return e};return n.d(t,"a",t),t},n.o=function(e,t){return Object.prototype.hasOwnProperty.call(e,t)},n.p="",n(n.s=4)}([function(e,t,n){"use strict";Object.defineProperty(t,"__esModule",{value:!0});var r=function(){var e=/d{1,4}|m{1,4}|yy(?:yy)?|([HhMsTt])\1?|[LloSZ]|"[^"]*"|'[^']*'/g,t=/\b(?:[PMCEA][SDP]T|(?:Pacific|Mountain|Central|Eastern|Atlantic) (?:Standard|Daylight|Prevailing) Time|(?:GMT|UTC)(?:[-+]\d{4})?)\b/g,n=/[^-+\dA-Z]/g,o=function(e,t){for(e=String(e),t=t||2;e.length99?Math.round(v/10):v),t:d<12?"a":"p",tt:d<12?"am":"pm",T:d<12?"A":"P",TT:d<12?"AM":"PM",Z:i?"UTC":(String(u).match(t)||[""]).pop().replace(n,""),o:(b>0?"-":"+")+o(100*Math.floor(Math.abs(b)/60)+Math.abs(b)%60,4),S:["th","st","nd","rd"][c%10>3?0:(c%100-c%10!=10)*c%10]};return a.replace(e,function(e){return e in M?M[e]:e.slice(1,e.length-1)})}}();r.masks={default:"ddd mmm dd yyyy HH:MM:ss",shortDate:"m/d/yy",mediumDate:"mmm d, yyyy",longDate:"mmmm d, yyyy",fullDate:"dddd, mmmm d, yyyy",shortTime:"h:MM TT",mediumTime:"h:MM:ss TT",longTime:"h:MM:ss TT Z",isoDate:"yyyy-mm-dd",isoTime:"HH:MM:ss",isoDateTime:"yyyy-mm-dd'T'HH:MM:ss",isoUtcDateTime:"UTC:yyyy-mm-dd'T'HH:MM:ss'Z'"},r.i18n={dayNames:["Sun","Mon","Tue","Wed","Thu","Fri","Sat","Sunday","Monday","Tuesday","Wednesday","Thursday","Friday","Saturday"],monthNames:["Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec","January","February","March","April","May","June","July","August","September","October","November","December"]},void 0===Date.prototype.format&&(Date.prototype.format=function(e,t){return r(this,e,t)}),t.default=r},function(e,t,n){"use strict";Object.defineProperty(t,"__esModule",{value:!0}),t.backwardCompatibility=t.easyDate=t.EasyDate=void 0;var r=function(){function e(e,t){for(var n=0;n1?"s":"")}},{key:"process",value:function(e){var t=this.conversionType,n=this.timeProcessor,r=this.now||new Date;return{minute:function(){return n(r,r.setMinutes,r.getMinutes,e)},hour:function(){return n(r,r.setHours,r.getHours,e)},day:function(){return n(r,r.setDate,r.getDate,e)},week:function(){return null},month:function(){return n(r,r.setMonth,r.getMonth,e)},year:function(){return n(r,r.setFullYear,r.getFullYear,e)}}[t]()}}]),e}(),s=function(){var e=this;this.timeProcessor=function(t,n,r,o){var u=e.value;return{ago:function(){return n.call(t,r.call(t)-u),a.formatDate(t,o)},fromNow:function(){return n.call(t,r.call(t)+u),a.formatDate(t,o)}}}};t.EasyDate=a,t.easyDate=function(e){var t=function(){return new i(e,"day")},n=function(){return new i(e,"month")},r=function(){return new i(e,"year")},o=function(){return new i(e,"hour")},u=function(){return new i(e,"minute")};return{minute:u,minutes:u,hour:o,hours:o,day:t,days:t,month:n,months:n,year:r,years:r}},t.backwardCompatibility=function(){var e=function(){return new i(this,"day")},t=function(){return new i(this,"month")},n=function(){return new i(this,"year")},r=function(){return new i(this,"hour")};Number.prototype.day=e,Number.prototype.days=e,Number.prototype.month=t,Number.prototype.months=t,Number.prototype.years=n,Number.prototype.year=n,Number.prototype.hours=r,Number.prototype.hour=r,Number.prototype.minute=function(){return new i(this,"minute")},Object.assign(Date,{today:function(e){return a.today(e)},yesterday:function(e){return a.yesterday(e)},tomorrow:function(e){return a.tomorrow(e)},tommorrow:function(e){return a.tomorrow(e)}})}},,,function(e,t,n){e.exports=n(1)}])}); -------------------------------------------------------------------------------- /easy-date.js: -------------------------------------------------------------------------------- 1 | (function webpackUniversalModuleDefinition(root, factory) { 2 | if(typeof exports === 'object' && typeof module === 'object') 3 | module.exports = factory(); 4 | else if(typeof define === 'function' && define.amd) 5 | define([], factory); 6 | else { 7 | var a = factory(); 8 | for(var i in a) (typeof exports === 'object' ? exports : root)[i] = a[i]; 9 | } 10 | })(window, function() { 11 | return /******/ (function(modules) { // webpackBootstrap 12 | /******/ // The module cache 13 | /******/ var installedModules = {}; 14 | /******/ 15 | /******/ // The require function 16 | /******/ function __webpack_require__(moduleId) { 17 | /******/ 18 | /******/ // Check if module is in cache 19 | /******/ if(installedModules[moduleId]) { 20 | /******/ return installedModules[moduleId].exports; 21 | /******/ } 22 | /******/ // Create a new module (and put it into the cache) 23 | /******/ var module = installedModules[moduleId] = { 24 | /******/ i: moduleId, 25 | /******/ l: false, 26 | /******/ exports: {} 27 | /******/ }; 28 | /******/ 29 | /******/ // Execute the module function 30 | /******/ modules[moduleId].call(module.exports, module, module.exports, __webpack_require__); 31 | /******/ 32 | /******/ // Flag the module as loaded 33 | /******/ module.l = true; 34 | /******/ 35 | /******/ // Return the exports of the module 36 | /******/ return module.exports; 37 | /******/ } 38 | /******/ 39 | /******/ 40 | /******/ // expose the modules object (__webpack_modules__) 41 | /******/ __webpack_require__.m = modules; 42 | /******/ 43 | /******/ // expose the module cache 44 | /******/ __webpack_require__.c = installedModules; 45 | /******/ 46 | /******/ // define getter function for harmony exports 47 | /******/ __webpack_require__.d = function(exports, name, getter) { 48 | /******/ if(!__webpack_require__.o(exports, name)) { 49 | /******/ Object.defineProperty(exports, name, { enumerable: true, get: getter }); 50 | /******/ } 51 | /******/ }; 52 | /******/ 53 | /******/ // define __esModule on exports 54 | /******/ __webpack_require__.r = function(exports) { 55 | /******/ if(typeof Symbol !== 'undefined' && Symbol.toStringTag) { 56 | /******/ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' }); 57 | /******/ } 58 | /******/ Object.defineProperty(exports, '__esModule', { value: true }); 59 | /******/ }; 60 | /******/ 61 | /******/ // create a fake namespace object 62 | /******/ // mode & 1: value is a module id, require it 63 | /******/ // mode & 2: merge all properties of value into the ns 64 | /******/ // mode & 4: return value when already ns object 65 | /******/ // mode & 8|1: behave like require 66 | /******/ __webpack_require__.t = function(value, mode) { 67 | /******/ if(mode & 1) value = __webpack_require__(value); 68 | /******/ if(mode & 8) return value; 69 | /******/ if((mode & 4) && typeof value === 'object' && value && value.__esModule) return value; 70 | /******/ var ns = Object.create(null); 71 | /******/ __webpack_require__.r(ns); 72 | /******/ Object.defineProperty(ns, 'default', { enumerable: true, value: value }); 73 | /******/ if(mode & 2 && typeof value != 'string') for(var key in value) __webpack_require__.d(ns, key, function(key) { return value[key]; }.bind(null, key)); 74 | /******/ return ns; 75 | /******/ }; 76 | /******/ 77 | /******/ // getDefaultExport function for compatibility with non-harmony modules 78 | /******/ __webpack_require__.n = function(module) { 79 | /******/ var getter = module && module.__esModule ? 80 | /******/ function getDefault() { return module['default']; } : 81 | /******/ function getModuleExports() { return module; }; 82 | /******/ __webpack_require__.d(getter, 'a', getter); 83 | /******/ return getter; 84 | /******/ }; 85 | /******/ 86 | /******/ // Object.prototype.hasOwnProperty.call 87 | /******/ __webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); }; 88 | /******/ 89 | /******/ // __webpack_public_path__ 90 | /******/ __webpack_require__.p = ""; 91 | /******/ 92 | /******/ 93 | /******/ // Load entry module and return exports 94 | /******/ return __webpack_require__(__webpack_require__.s = 1); 95 | /******/ }) 96 | /************************************************************************/ 97 | /******/ ({ 98 | 99 | /***/ "./src/bundled.js": 100 | /*!************************!*\ 101 | !*** ./src/bundled.js ***! 102 | \************************/ 103 | /*! no static exports found */ 104 | /***/ (function(module, exports, __webpack_require__) { 105 | 106 | "use strict"; 107 | eval("\n\nObject.defineProperty(exports, \"__esModule\", {\n value: true\n});\n\nvar _easyDate = __webpack_require__(/*! ./easy-date */ \"./src/easy-date.js\");\n\nObject.keys(_easyDate).forEach(function (key) {\n if (key === \"default\" || key === \"__esModule\") return;\n Object.defineProperty(exports, key, {\n enumerable: true,\n get: function get() {\n return _easyDate[key];\n }\n });\n});\n\nvar _dateFormat = __webpack_require__(/*! ./date-format */ \"./src/date-format.js\");\n\nObject.keys(_dateFormat).forEach(function (key) {\n if (key === \"default\" || key === \"__esModule\") return;\n Object.defineProperty(exports, key, {\n enumerable: true,\n get: function get() {\n return _dateFormat[key];\n }\n });\n});\n\n//# sourceURL=webpack:///./src/bundled.js?"); 108 | 109 | /***/ }), 110 | 111 | /***/ "./src/date-format.js": 112 | /*!****************************!*\ 113 | !*** ./src/date-format.js ***! 114 | \****************************/ 115 | /*! no static exports found */ 116 | /***/ (function(module, exports, __webpack_require__) { 117 | 118 | "use strict"; 119 | eval("\n\nObject.defineProperty(exports, \"__esModule\", {\n value: true\n});\n/*\n * Date Format 1.2.3\n * (c) 2007-2009 Steven Levithan \n * MIT license\n *\n * Includes enhancements by Scott Trenda \n * and Kris Kowal \n *\n * Accepts a date, a mask, or a date and a mask.\n * Returns a formatted version of the given date.\n * The date defaults to the current date/time.\n * The mask defaults to dateFormat.masks.default.\n */\n\nvar dateFormat = function () {\n var token = /d{1,4}|m{1,4}|yy(?:yy)?|([HhMsTt])\\1?|[LloSZ]|\"[^\"]*\"|'[^']*'/g;\n var timezone = /\\b(?:[PMCEA][SDP]T|(?:Pacific|Mountain|Central|Eastern|Atlantic) (?:Standard|Daylight|Prevailing) Time|(?:GMT|UTC)(?:[-+]\\d{4})?)\\b/g;\n var timezoneClip = /[^-+\\dA-Z]/g;\n\n var pad = function pad(val, len) {\n val = String(val);\n len = len || 2;\n while (val.length < len) {\n val = '0' + val;\n }\n return val;\n };\n\n // Regexes and supporting functions are cached through closure\n return function (date, mask, utc) {\n var dF = dateFormat;\n // You can't provide utc if you skip other args (use the \"UTC:\" mask prefix)\n if (arguments.length === 1 && Object.prototype.toString.call(date) === '[object String]' && !/\\d/.test(date)) {\n mask = date;\n date = undefined;\n }\n // Passing date through Date applies Date.parse, if necessary\n date = date ? new Date(date) : new Date();\n if (isNaN(date)) {\n throw SyntaxError('invalid date');\n }\n mask = String(dF.masks[mask] || mask || dF.masks['default']);\n // Allow setting the utc argument via the mask\n if (mask.slice(0, 4) === 'UTC:') {\n mask = mask.slice(4);\n utc = true;\n }\n var _ = utc ? 'getUTC' : 'get';\n var d = date[_ + 'Date']();\n var D = date[_ + 'Day']();\n var m = date[_ + 'Month']();\n var y = date[_ + 'FullYear']();\n var H = date[_ + 'Hours']();\n var M = date[_ + 'Minutes']();\n var s = date[_ + 'Seconds']();\n var L = date[_ + 'Milliseconds']();\n var o = utc ? 0 : date.getTimezoneOffset();\n var flags = {\n d: d,\n dd: pad(d),\n ddd: dF.i18n.dayNames[D],\n dddd: dF.i18n.dayNames[D + 7],\n m: m + 1,\n mm: pad(m + 1),\n mmm: dF.i18n.monthNames[m],\n mmmm: dF.i18n.monthNames[m + 12],\n yy: String(y).slice(2),\n yyyy: y,\n h: H % 12 || 12,\n hh: pad(H % 12 || 12),\n H: H,\n HH: pad(H),\n M: M,\n MM: pad(M),\n s: s,\n ss: pad(s),\n l: pad(L, 3),\n L: pad(L > 99 ? Math.round(L / 10) : L),\n t: H < 12 ? 'a' : 'p',\n tt: H < 12 ? 'am' : 'pm',\n T: H < 12 ? 'A' : 'P',\n TT: H < 12 ? 'AM' : 'PM',\n Z: utc ? 'UTC' : (String(date).match(timezone) || ['']).pop().replace(timezoneClip, ''),\n o: (o > 0 ? '-' : '+') + pad(Math.floor(Math.abs(o) / 60) * 100 + Math.abs(o) % 60, 4),\n S: ['th', 'st', 'nd', 'rd'][d % 10 > 3 ? 0 : (d % 100 - d % 10 !== 10) * d % 10]\n };\n return mask.replace(token, function ($0) {\n if ($0 in flags) {\n return flags[$0];\n } else {\n return $0.slice(1, $0.length - 1);\n }\n });\n };\n}();\n// Some common format strings\ndateFormat.masks = {\n 'default': 'ddd mmm dd yyyy HH:MM:ss',\n shortDate: 'm/d/yy',\n mediumDate: 'mmm d, yyyy',\n longDate: 'mmmm d, yyyy',\n fullDate: 'dddd, mmmm d, yyyy',\n shortTime: 'h:MM TT',\n mediumTime: 'h:MM:ss TT',\n longTime: 'h:MM:ss TT Z',\n isoDate: 'yyyy-mm-dd',\n isoTime: 'HH:MM:ss',\n isoDateTime: 'yyyy-mm-dd\\'T\\'HH:MM:ss',\n isoUtcDateTime: 'UTC:yyyy-mm-dd\\'T\\'HH:MM:ss\\'Z\\''\n};\n// Internationalization strings\ndateFormat.i18n = {\n dayNames: ['Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday'],\n monthNames: ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec', 'January', 'February', 'March', 'April', 'May', 'June', 'July', 'August', 'September', 'October', 'November', 'December']\n};\n\n// For convenience...\nif (Date.prototype.format === undefined) {\n Date.prototype.format = function (mask, utc) {\n return dateFormat(this, mask, utc);\n };\n}\n\nexports.default = dateFormat;\n\n//# sourceURL=webpack:///./src/date-format.js?"); 120 | 121 | /***/ }), 122 | 123 | /***/ "./src/easy-date.js": 124 | /*!**************************!*\ 125 | !*** ./src/easy-date.js ***! 126 | \**************************/ 127 | /*! no static exports found */ 128 | /***/ (function(module, exports, __webpack_require__) { 129 | 130 | "use strict"; 131 | eval("\n\nObject.defineProperty(exports, \"__esModule\", {\n value: true\n});\nexports.backwardCompatibility = exports.easyDate = exports.EasyDate = undefined;\n\nvar _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if (\"value\" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();\n\nvar _dateFormat = __webpack_require__(/*! ./date-format */ \"./src/date-format.js\");\n\nvar _dateFormat2 = _interopRequireDefault(_dateFormat);\n\nfunction _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }\n\nfunction _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError(\"Cannot call a class as a function\"); } }\n\nvar EasyDate = function () {\n function EasyDate(date) {\n _classCallCheck(this, EasyDate);\n\n if (typeof date === 'string') {\n this._date = new Date(date);\n } else {\n this._date = date;\n }\n }\n\n _createClass(EasyDate, [{\n key: \"getDate\",\n value: function getDate() {\n return this._date;\n }\n }, {\n key: \"format\",\n value: function format(mask) {\n return (0, _dateFormat2.default)(this._date, mask);\n }\n }], [{\n key: \"formatDate\",\n value: function formatDate(date, mask) {\n if (!!mask) {\n return (0, _dateFormat2.default)(date, mask);\n } else {\n return date;\n }\n }\n }, {\n key: \"today\",\n value: function today(mask) {\n return EasyDate.formatDate(new Date(), mask);\n }\n }, {\n key: \"yesterday\",\n value: function yesterday(mask) {\n return new EasyD(1, 'day').ago(mask);\n }\n }, {\n key: \"tomorrow\",\n value: function tomorrow(mask) {\n return new EasyD(1, 'day').fromNow(mask);\n }\n }]);\n\n return EasyDate;\n}();\n\nvar EasyD = function () {\n function EasyD(value, conversionType) {\n _classCallCheck(this, EasyD);\n\n _initialiseProps.call(this);\n\n this.value = parseInt(value);\n this.conversionType = conversionType;\n }\n\n _createClass(EasyD, [{\n key: \"fromNow\",\n value: function fromNow(mask) {\n var processor = this.process(mask);\n if (processor) {\n return processor.fromNow();\n } else {\n return \"Processor not found.\";\n }\n }\n }, {\n key: \"ago\",\n value: function ago(mask) {\n var processor = this.process(mask);\n if (processor) {\n return processor.ago();\n } else {\n return \"Processor not found.\";\n }\n }\n }, {\n key: \"since\",\n value: function since(date, mask) {\n this.now = new Date(date.valueOf());\n return this.fromNow(mask);\n }\n }, {\n key: \"until\",\n value: function until(date, mask) {\n this.now = new Date(date.valueOf());\n return this.ago(mask);\n }\n }, {\n key: \"before\",\n value: function before(date, mask) {\n return this.until(date, mask);\n }\n }, {\n key: \"toString\",\n value: function toString() {\n return this.value + \" \" + this.conversionType + (this.value > 1 ? 's' : '');\n }\n }, {\n key: \"process\",\n value: function process(mask) {\n var conversionType = this.conversionType,\n timeProcessor = this.timeProcessor;\n\n var now = this.now || new Date();\n return {\n minute: function minute() {\n return timeProcessor(now, now.setMinutes, now.getMinutes, mask);\n },\n hour: function hour() {\n return timeProcessor(now, now.setHours, now.getHours, mask);\n },\n day: function day() {\n return timeProcessor(now, now.setDate, now.getDate, mask);\n },\n week: function week() {\n return null;\n },\n month: function month() {\n return timeProcessor(now, now.setMonth, now.getMonth, mask);\n },\n year: function year() {\n return timeProcessor(now, now.setFullYear, now.getFullYear, mask);\n }\n }[conversionType]();\n }\n }]);\n\n return EasyD;\n}();\n\nvar _initialiseProps = function _initialiseProps() {\n var _this = this;\n\n this.timeProcessor = function (now, set, get, mask) {\n var value = _this.value;\n\n return {\n ago: function ago() {\n set.call(now, get.call(now) - value);\n return EasyDate.formatDate(now, mask);\n },\n fromNow: function fromNow() {\n set.call(now, get.call(now) + value);\n return EasyDate.formatDate(now, mask);\n }\n };\n };\n};\n\nfunction easyDate(value) {\n var days = function days() {\n return new EasyD(value, 'day');\n };\n\n var months = function months() {\n return new EasyD(value, 'month');\n };\n\n var years = function years() {\n return new EasyD(value, 'year');\n };\n\n var hours = function hours() {\n return new EasyD(value, 'hour');\n };\n\n var minutes = function minutes() {\n return new EasyD(value, 'minute');\n };\n\n return {\n minute: minutes,\n minutes: minutes,\n hour: hours,\n hours: hours,\n day: days,\n days: days,\n month: months,\n months: months,\n year: years,\n years: years\n };\n}\n\nfunction backwardCompatibility() {\n\n var days = function days() {\n return new EasyD(this, 'day');\n };\n\n var months = function months() {\n return new EasyD(this, 'month');\n };\n\n var years = function years() {\n return new EasyD(this, 'year');\n };\n\n var hours = function hours() {\n return new EasyD(this, 'hour');\n };\n\n var minutes = function minutes() {\n return new EasyD(this, 'minute');\n };\n\n // $FlowFixMe\n Number.prototype.day = days;\n // $FlowFixMe\n Number.prototype.days = days;\n // $FlowFixMe\n Number.prototype.month = months;\n // $FlowFixMe\n Number.prototype.months = months;\n // $FlowFixMe\n Number.prototype.years = years;\n // $FlowFixMe\n Number.prototype.year = years;\n // $FlowFixMe\n Number.prototype.hours = hours;\n // $FlowFixMe\n Number.prototype.hour = hours;\n // $FlowFixMe\n Number.prototype.minute = minutes;\n\n // $FlowFixMe\n Object.assign(Date, {\n today: function today(mask) {\n return EasyDate.today(mask);\n },\n yesterday: function yesterday(mask) {\n return EasyDate.yesterday(mask);\n },\n tomorrow: function tomorrow(mask) {\n return EasyDate.tomorrow(mask);\n },\n tommorrow: function tommorrow(mask) {\n return EasyDate.tomorrow(mask);\n }\n });\n}\n\nexports.EasyDate = EasyDate;\nexports.easyDate = easyDate;\nexports.backwardCompatibility = backwardCompatibility;\n\n//# sourceURL=webpack:///./src/easy-date.js?"); 132 | 133 | /***/ }), 134 | 135 | /***/ 1: 136 | /*!******************************!*\ 137 | !*** multi ./src/bundled.js ***! 138 | \******************************/ 139 | /*! no static exports found */ 140 | /***/ (function(module, exports, __webpack_require__) { 141 | 142 | eval("module.exports = __webpack_require__(/*! ./src/bundled.js */\"./src/bundled.js\");\n\n\n//# sourceURL=webpack:///multi_./src/bundled.js?"); 143 | 144 | /***/ }) 145 | 146 | /******/ }); 147 | }); -------------------------------------------------------------------------------- /easy-date.min.js: -------------------------------------------------------------------------------- 1 | !function(e,t){if("object"==typeof exports&&"object"==typeof module)module.exports=t();else if("function"==typeof define&&define.amd)define([],t);else{var n=t();for(var r in n)("object"==typeof exports?exports:e)[r]=n[r]}}(window,function(){return function(e){var t={};function n(r){if(t[r])return t[r].exports;var o=t[r]={i:r,l:!1,exports:{}};return e[r].call(o.exports,o,o.exports,n),o.l=!0,o.exports}return n.m=e,n.c=t,n.d=function(e,t,r){n.o(e,t)||Object.defineProperty(e,t,{enumerable:!0,get:r})},n.r=function(e){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},n.t=function(e,t){if(1&t&&(e=n(e)),8&t)return e;if(4&t&&"object"==typeof e&&e&&e.__esModule)return e;var r=Object.create(null);if(n.r(r),Object.defineProperty(r,"default",{enumerable:!0,value:e}),2&t&&"string"!=typeof e)for(var o in e)n.d(r,o,function(t){return e[t]}.bind(null,o));return r},n.n=function(e){var t=e&&e.__esModule?function(){return e.default}:function(){return e};return n.d(t,"a",t),t},n.o=function(e,t){return Object.prototype.hasOwnProperty.call(e,t)},n.p="",n(n.s=3)}([function(e,t,n){"use strict";Object.defineProperty(t,"__esModule",{value:!0});var r=function(){var e=/d{1,4}|m{1,4}|yy(?:yy)?|([HhMsTt])\1?|[LloSZ]|"[^"]*"|'[^']*'/g,t=/\b(?:[PMCEA][SDP]T|(?:Pacific|Mountain|Central|Eastern|Atlantic) (?:Standard|Daylight|Prevailing) Time|(?:GMT|UTC)(?:[-+]\d{4})?)\b/g,n=/[^-+\dA-Z]/g,o=function(e,t){for(e=String(e),t=t||2;e.length99?Math.round(v/10):v),t:m<12?"a":"p",tt:m<12?"am":"pm",T:m<12?"A":"P",TT:m<12?"AM":"PM",Z:i?"UTC":(String(u).match(t)||[""]).pop().replace(n,""),o:(b>0?"-":"+")+o(100*Math.floor(Math.abs(b)/60)+Math.abs(b)%60,4),S:["th","st","nd","rd"][f%10>3?0:(f%100-f%10!=10)*f%10]};return a.replace(e,function(e){return e in M?M[e]:e.slice(1,e.length-1)})}}();r.masks={default:"ddd mmm dd yyyy HH:MM:ss",shortDate:"m/d/yy",mediumDate:"mmm d, yyyy",longDate:"mmmm d, yyyy",fullDate:"dddd, mmmm d, yyyy",shortTime:"h:MM TT",mediumTime:"h:MM:ss TT",longTime:"h:MM:ss TT Z",isoDate:"yyyy-mm-dd",isoTime:"HH:MM:ss",isoDateTime:"yyyy-mm-dd'T'HH:MM:ss",isoUtcDateTime:"UTC:yyyy-mm-dd'T'HH:MM:ss'Z'"},r.i18n={dayNames:["Sun","Mon","Tue","Wed","Thu","Fri","Sat","Sunday","Monday","Tuesday","Wednesday","Thursday","Friday","Saturday"],monthNames:["Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec","January","February","March","April","May","June","July","August","September","October","November","December"]},void 0===Date.prototype.format&&(Date.prototype.format=function(e,t){return r(this,e,t)}),t.default=r},function(e,t,n){"use strict";Object.defineProperty(t,"__esModule",{value:!0}),t.backwardCompatibility=t.easyDate=t.EasyDate=void 0;var r=function(){function e(e,t){for(var n=0;n1?"s":"")}},{key:"process",value:function(e){var t=this.conversionType,n=this.timeProcessor,r=this.now||new Date;return{minute:function(){return n(r,r.setMinutes,r.getMinutes,e)},hour:function(){return n(r,r.setHours,r.getHours,e)},day:function(){return n(r,r.setDate,r.getDate,e)},week:function(){return null},month:function(){return n(r,r.setMonth,r.getMonth,e)},year:function(){return n(r,r.setFullYear,r.getFullYear,e)}}[t]()}}]),e}(),s=function(){var e=this;this.timeProcessor=function(t,n,r,o){var u=e.value;return{ago:function(){return n.call(t,r.call(t)-u),a.formatDate(t,o)},fromNow:function(){return n.call(t,r.call(t)+u),a.formatDate(t,o)}}}};t.EasyDate=a,t.easyDate=function(e){var t=function(){return new i(e,"day")},n=function(){return new i(e,"month")},r=function(){return new i(e,"year")},o=function(){return new i(e,"hour")},u=function(){return new i(e,"minute")};return{minute:u,minutes:u,hour:o,hours:o,day:t,days:t,month:n,months:n,year:r,years:r}},t.backwardCompatibility=function(){var e=function(){return new i(this,"day")},t=function(){return new i(this,"month")},n=function(){return new i(this,"year")},r=function(){return new i(this,"hour")};Number.prototype.day=e,Number.prototype.days=e,Number.prototype.month=t,Number.prototype.months=t,Number.prototype.years=n,Number.prototype.year=n,Number.prototype.hours=r,Number.prototype.hour=r,Number.prototype.minute=function(){return new i(this,"minute")},Object.assign(Date,{today:function(e){return a.today(e)},yesterday:function(e){return a.yesterday(e)},tomorrow:function(e){return a.tomorrow(e)},tommorrow:function(e){return a.tomorrow(e)}})}},function(e,t,n){"use strict";Object.defineProperty(t,"__esModule",{value:!0});var r=n(1);Object.keys(r).forEach(function(e){"default"!==e&&"__esModule"!==e&&Object.defineProperty(t,e,{enumerable:!0,get:function(){return r[e]}})});var o=n(0);Object.keys(o).forEach(function(e){"default"!==e&&"__esModule"!==e&&Object.defineProperty(t,e,{enumerable:!0,get:function(){return o[e]}})})},function(e,t,n){e.exports=n(2)}])}); -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "easy-date", 3 | "main": "easy-date.js", 4 | "description": "EasyDate is a Javascript extension for easy dates manipulations which is heavily inspired by Rails ActiveSupport::Duration class.", 5 | "version": "1.2.7", 6 | "keywords": [ 7 | "EasyDate", 8 | "Easy Date", 9 | "Rails Date", 10 | "Javascript Date", 11 | "Rails like javascript date", 12 | "ruby date", 13 | "Format", 14 | "Javascript date format", 15 | "date format" 16 | ], 17 | "repository": { 18 | "type": "git", 19 | "url": "git@github.com:melvinsembrano/easy-date.git" 20 | }, 21 | "author": "Melvin Sembrano (https://github.com/melvinsembrano/easy-date)", 22 | "license": "MIT", 23 | "devDependencies": { 24 | "babel-cli": "^6.26.0", 25 | "flow": "^0.2.3", 26 | "flow-bin": "^0.75.0", 27 | "flow-typed": "^2.4.0", 28 | "jest": "^23.2.0", 29 | "uglifyjs-webpack-plugin": "^1.2.7", 30 | "webpack": "^4.8.3", 31 | "webpack-cli": "^3.0.8", 32 | "webpack-merge": "^4.1.3" 33 | }, 34 | "scripts": { 35 | "build": "webpack --config webpack.config.dev.js", 36 | "build:min": "NODE_ENV=production webpack -p --config webpack.config.prod.js", 37 | "build:all": "yarn build && yarn build:min", 38 | "test": "flow && yarn build && jest", 39 | "tagRelease": "PKGV=$(cat package.json | grep version | head -1 | awk -F: '{ print $2 }' | sed 's/[\",]//g' | tr -d '[[:space:]]') && git tag v$PKGV", 40 | "release:push": "git push origin master && git push --tags", 41 | "commit": "PKGV=$(cat package.json | grep version | head -1 | awk -F: '{ print $2 }' | sed 's/[\",]//g' | tr -d '[[:space:]]') && git commit bower.json easy-date.min.js easy-date-light.min.js package.json -m \"Release v$PKGV\"" 42 | }, 43 | "dependencies": { 44 | "babel-loader": "^7.1.4", 45 | "babel-plugin-transform-class-properties": "^6.24.1", 46 | "babel-preset-env": "^1.7.0", 47 | "babel-preset-flow": "^6.23.0" 48 | }, 49 | "jest": { 50 | "testRegex": "test/.*(Spec|Test).js", 51 | "verbose": true 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /src/.keep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/melvinsembrano/easy-date/8c40be518e4b9fd9f9d5d8477f0ec5ffd2a53b7e/src/.keep -------------------------------------------------------------------------------- /src/bundled.js: -------------------------------------------------------------------------------- 1 | export * from './easy-date' 2 | export * from './date-format' 3 | -------------------------------------------------------------------------------- /src/date-format.js: -------------------------------------------------------------------------------- 1 | /* 2 | * Date Format 1.2.3 3 | * (c) 2007-2009 Steven Levithan 4 | * MIT license 5 | * 6 | * Includes enhancements by Scott Trenda 7 | * and Kris Kowal 8 | * 9 | * Accepts a date, a mask, or a date and a mask. 10 | * Returns a formatted version of the given date. 11 | * The date defaults to the current date/time. 12 | * The mask defaults to dateFormat.masks.default. 13 | */ 14 | 15 | var dateFormat = (function() { 16 | let token = /d{1,4}|m{1,4}|yy(?:yy)?|([HhMsTt])\1?|[LloSZ]|"[^"]*"|'[^']*'/g; 17 | let timezone = /\b(?:[PMCEA][SDP]T|(?:Pacific|Mountain|Central|Eastern|Atlantic) (?:Standard|Daylight|Prevailing) Time|(?:GMT|UTC)(?:[-+]\d{4})?)\b/g; 18 | let timezoneClip = /[^-+\dA-Z]/g; 19 | 20 | let pad = function(val, len) { 21 | val = String(val); 22 | len = len || 2; 23 | while (val.length < len) { 24 | val = `0${val}`; 25 | } 26 | return val; 27 | }; 28 | 29 | // Regexes and supporting functions are cached through closure 30 | return function(date, mask, utc) { 31 | let dF = dateFormat; 32 | // You can't provide utc if you skip other args (use the "UTC:" mask prefix) 33 | if ((arguments.length === 1) && (Object.prototype.toString.call(date) === '[object String]') && !/\d/.test(date)) { 34 | mask = date; 35 | date = undefined; 36 | } 37 | // Passing date through Date applies Date.parse, if necessary 38 | date = date ? new Date(date) : new Date; 39 | if (isNaN(date)) { 40 | throw SyntaxError('invalid date'); 41 | } 42 | mask = String(dF.masks[mask] || mask || dF.masks['default']); 43 | // Allow setting the utc argument via the mask 44 | if (mask.slice(0, 4) === 'UTC:') { 45 | mask = mask.slice(4); 46 | utc = true; 47 | } 48 | let _ = utc ? 'getUTC' : 'get'; 49 | let d = date[_ + 'Date'](); 50 | let D = date[_ + 'Day'](); 51 | let m = date[_ + 'Month'](); 52 | let y = date[_ + 'FullYear'](); 53 | let H = date[_ + 'Hours'](); 54 | let M = date[_ + 'Minutes'](); 55 | let s = date[_ + 'Seconds'](); 56 | let L = date[_ + 'Milliseconds'](); 57 | let o = utc ? 0 : date.getTimezoneOffset(); 58 | let flags = { 59 | d, 60 | dd: pad(d), 61 | ddd: dF.i18n.dayNames[D], 62 | dddd: dF.i18n.dayNames[D + 7], 63 | m: m + 1, 64 | mm: pad(m + 1), 65 | mmm: dF.i18n.monthNames[m], 66 | mmmm: dF.i18n.monthNames[m + 12], 67 | yy: String(y).slice(2), 68 | yyyy: y, 69 | h: (H % 12) || 12, 70 | hh: pad((H % 12) || 12), 71 | H, 72 | HH: pad(H), 73 | M, 74 | MM: pad(M), 75 | s, 76 | ss: pad(s), 77 | l: pad(L, 3), 78 | L: pad(L > 99 ? Math.round(L / 10) : L), 79 | t: H < 12 ? 'a' : 'p', 80 | tt: H < 12 ? 'am' : 'pm', 81 | T: H < 12 ? 'A' : 'P', 82 | TT: H < 12 ? 'AM' : 'PM', 83 | Z: utc ? 'UTC' : (String(date).match(timezone) || [ '' ]).pop().replace(timezoneClip, ''), 84 | o: (o > 0 ? '-' : '+') + pad((Math.floor(Math.abs(o) / 60) * 100) + (Math.abs(o) % 60), 4), 85 | S: [ 86 | 'th', 87 | 'st', 88 | 'nd', 89 | 'rd' 90 | ][(d % 10) > 3 ? 0 : ((((d % 100) - (d % 10)) !== 10) * d) % 10] 91 | }; 92 | return mask.replace(token, function($0) { 93 | if ($0 in flags) { return flags[$0]; } else { return $0.slice(1, $0.length - 1); } 94 | }); 95 | }; 96 | })(); 97 | // Some common format strings 98 | dateFormat.masks = { 99 | 'default': 'ddd mmm dd yyyy HH:MM:ss', 100 | shortDate: 'm/d/yy', 101 | mediumDate: 'mmm d, yyyy', 102 | longDate: 'mmmm d, yyyy', 103 | fullDate: 'dddd, mmmm d, yyyy', 104 | shortTime: 'h:MM TT', 105 | mediumTime: 'h:MM:ss TT', 106 | longTime: 'h:MM:ss TT Z', 107 | isoDate: 'yyyy-mm-dd', 108 | isoTime: 'HH:MM:ss', 109 | isoDateTime: 'yyyy-mm-dd\'T\'HH:MM:ss', 110 | isoUtcDateTime: 'UTC:yyyy-mm-dd\'T\'HH:MM:ss\'Z\'' 111 | }; 112 | // Internationalization strings 113 | dateFormat.i18n = { 114 | dayNames: [ 115 | 'Sun', 116 | 'Mon', 117 | 'Tue', 118 | 'Wed', 119 | 'Thu', 120 | 'Fri', 121 | 'Sat', 122 | 'Sunday', 123 | 'Monday', 124 | 'Tuesday', 125 | 'Wednesday', 126 | 'Thursday', 127 | 'Friday', 128 | 'Saturday' 129 | ], 130 | monthNames: [ 131 | 'Jan', 132 | 'Feb', 133 | 'Mar', 134 | 'Apr', 135 | 'May', 136 | 'Jun', 137 | 'Jul', 138 | 'Aug', 139 | 'Sep', 140 | 'Oct', 141 | 'Nov', 142 | 'Dec', 143 | 'January', 144 | 'February', 145 | 'March', 146 | 'April', 147 | 'May', 148 | 'June', 149 | 'July', 150 | 'August', 151 | 'September', 152 | 'October', 153 | 'November', 154 | 'December' 155 | ] 156 | }; 157 | 158 | // For convenience... 159 | if (Date.prototype.format === undefined) { 160 | Date.prototype.format = function(mask, utc) { 161 | return dateFormat(this, mask, utc); 162 | }; 163 | } 164 | 165 | export default dateFormat 166 | -------------------------------------------------------------------------------- /src/easy-date.js: -------------------------------------------------------------------------------- 1 | // @flow 2 | import dateFormat from './date-format' 3 | 4 | type ConversionType = "day" | "week" | "month" | "year" | "hour" | "minute" 5 | 6 | type TypeProcessor = { 7 | ago: () => Date | string, 8 | fromNow: () => Date | string, 9 | } 10 | 11 | class EasyDate { 12 | _date: Date 13 | 14 | constructor(date: Date | string) { 15 | if (typeof date === 'string') { 16 | this._date = new Date(date) 17 | } else { 18 | this._date = date 19 | } 20 | } 21 | 22 | getDate() { 23 | return this._date 24 | } 25 | 26 | format(mask: string) { 27 | return dateFormat(this._date, mask) 28 | } 29 | 30 | static formatDate(date: Date, mask?: string): Date | string { 31 | if (!!mask) { 32 | return dateFormat(date, mask) 33 | } else { 34 | return date 35 | } 36 | } 37 | 38 | static today(mask?: string) { 39 | return EasyDate.formatDate(new Date(), mask) 40 | } 41 | 42 | static yesterday(mask?: string) { 43 | return new EasyD(1, 'day').ago(mask) 44 | } 45 | 46 | static tomorrow(mask?: string) { 47 | return new EasyD(1, 'day').fromNow(mask) 48 | } 49 | } 50 | 51 | class EasyD { 52 | now: ?Date 53 | value: number 54 | conversionType: ConversionType 55 | 56 | constructor(value: number, conversionType: ConversionType) { 57 | this.value = parseInt(value) 58 | this.conversionType = conversionType 59 | } 60 | 61 | fromNow(mask?: string): Date | string { 62 | const processor = this.process(mask) 63 | if (processor) { 64 | return processor.fromNow() 65 | } else { 66 | return `Processor not found.` 67 | } 68 | } 69 | 70 | ago(mask?: string): Date | string { 71 | const processor = this.process(mask) 72 | if (processor) { 73 | return processor.ago() 74 | } else { 75 | return `Processor not found.` 76 | } 77 | } 78 | 79 | since(date: Date, mask?: string): Date | string { 80 | this.now = new Date(date.valueOf()) 81 | return this.fromNow(mask) 82 | } 83 | 84 | until(date: Date, mask?: string): Date | string { 85 | this.now = new Date(date.valueOf()); 86 | return this.ago(mask) 87 | } 88 | 89 | before(date: Date, mask?: string): Date | string { 90 | return this.until(date, mask) 91 | } 92 | 93 | toString(): string { 94 | return `${ this.value } ${ this.conversionType }${ this.value > 1 ? 's' : '' }`; 95 | } 96 | 97 | process(mask?: string): ?TypeProcessor { 98 | const { conversionType, timeProcessor } = this 99 | let now = this.now || new Date() 100 | return { 101 | minute(): ?TypeProcessor { 102 | return timeProcessor(now, now.setMinutes, now.getMinutes, mask) 103 | }, 104 | hour(): ?TypeProcessor { 105 | return timeProcessor(now, now.setHours, now.getHours, mask) 106 | }, 107 | day(): TypeProcessor { 108 | return timeProcessor(now, now.setDate, now.getDate, mask) 109 | }, 110 | week(): ?TypeProcessor { 111 | return null 112 | }, 113 | month(): ?TypeProcessor { 114 | return timeProcessor(now, now.setMonth, now.getMonth, mask) 115 | }, 116 | year(): ?TypeProcessor { 117 | return timeProcessor(now, now.setFullYear, now.getFullYear, mask) 118 | }, 119 | }[conversionType]() 120 | } 121 | 122 | timeProcessor = (now: Date, set: any, get: any, mask?: string): TypeProcessor => { 123 | const { value } = this 124 | return { 125 | ago(): Date | string { 126 | set.call(now, get.call(now) - value) 127 | return EasyDate.formatDate(now, mask); 128 | }, 129 | 130 | fromNow(): Date | string { 131 | set.call(now, get.call(now) + value) 132 | return EasyDate.formatDate(now, mask); 133 | } 134 | } 135 | } 136 | 137 | 138 | } 139 | 140 | function easyDate(value: number) { 141 | const days = function() { 142 | return new EasyD(value, 'day') 143 | } 144 | 145 | const months = function() { 146 | return new EasyD(value, 'month') 147 | } 148 | 149 | const years = function() { 150 | return new EasyD(value, 'year') 151 | } 152 | 153 | const hours = function() { 154 | return new EasyD(value, 'hour') 155 | } 156 | 157 | const minutes = function() { 158 | return new EasyD(value, 'minute') 159 | } 160 | 161 | return { 162 | minute: minutes, 163 | minutes: minutes, 164 | hour: hours, 165 | hours, 166 | day: days, 167 | days, 168 | month: months, 169 | months, 170 | year: years, 171 | years, 172 | } 173 | } 174 | 175 | function backwardCompatibility() { 176 | 177 | const days = function() { 178 | return new EasyD(this, 'day') 179 | } 180 | 181 | const months = function() { 182 | return new EasyD(this, 'month') 183 | } 184 | 185 | const years = function() { 186 | return new EasyD(this, 'year') 187 | } 188 | 189 | const hours = function() { 190 | return new EasyD(this, 'hour') 191 | } 192 | 193 | const minutes = function() { 194 | return new EasyD(this, 'minute') 195 | } 196 | 197 | // $FlowFixMe 198 | Number.prototype.day = days; 199 | // $FlowFixMe 200 | Number.prototype.days = days; 201 | // $FlowFixMe 202 | Number.prototype.month = months; 203 | // $FlowFixMe 204 | Number.prototype.months = months; 205 | // $FlowFixMe 206 | Number.prototype.years = years; 207 | // $FlowFixMe 208 | Number.prototype.year = years; 209 | // $FlowFixMe 210 | Number.prototype.hours = hours; 211 | // $FlowFixMe 212 | Number.prototype.hour = hours; 213 | // $FlowFixMe 214 | Number.prototype.minute = minutes; 215 | 216 | // $FlowFixMe 217 | Object.assign(Date, { 218 | 219 | today(mask?: string) { 220 | return EasyDate.today(mask); 221 | }, 222 | 223 | yesterday(mask?: string) { 224 | return EasyDate.yesterday(mask) 225 | }, 226 | 227 | tomorrow(mask?: string) { 228 | return EasyDate.tomorrow(mask) 229 | }, 230 | 231 | tommorrow(mask?: string) { 232 | return EasyDate.tomorrow(mask) 233 | }, 234 | 235 | }) 236 | } 237 | 238 | 239 | 240 | export { 241 | EasyDate, 242 | easyDate, 243 | backwardCompatibility, 244 | } 245 | -------------------------------------------------------------------------------- /test/.keep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/melvinsembrano/easy-date/8c40be518e4b9fd9f9d5d8477f0ec5ffd2a53b7e/test/.keep -------------------------------------------------------------------------------- /test/dateLegacySpec.js: -------------------------------------------------------------------------------- 1 | import { backwardCompatibility } from '../easy-date' 2 | backwardCompatibility() 3 | 4 | describe('Date', function() { 5 | it('will get the date today', function() { 6 | var now = new Date(); 7 | var today = Date.today(); 8 | expect(today.getDate()).toBe(now.getDate()); 9 | expect(today.getFullYear()).toBe(now.getFullYear()); 10 | expect(today.getMonth()).toBe(now.getMonth()); 11 | }); 12 | 13 | it('will get the date tommorrow', function() { 14 | var now = 1..day().fromNow() 15 | var today = Date.tomorrow(); 16 | expect(today.getDate()).toBe(now.getDate()); 17 | expect(today.getFullYear()).toBe(now.getFullYear()); 18 | expect(today.getMonth()).toBe(now.getMonth()); 19 | }); 20 | 21 | it('will get the date yesterday', function() { 22 | var now = 1..day().ago() 23 | var today = Date.yesterday(); 24 | expect(today.getDate()).toBe(now.getDate()); 25 | expect(today.getFullYear()).toBe(now.getFullYear()); 26 | expect(today.getMonth()).toBe(now.getMonth()); 27 | }); 28 | }); 29 | -------------------------------------------------------------------------------- /test/dateSpec.js: -------------------------------------------------------------------------------- 1 | import { easyDate, EasyDate } from '../easy-date' 2 | 3 | describe('Date', function() { 4 | it('will get the date today', function() { 5 | var now = new Date(); 6 | var today = EasyDate.today(); 7 | expect(today.getDate()).toBe(now.getDate()); 8 | expect(today.getFullYear()).toBe(now.getFullYear()); 9 | expect(today.getMonth()).toBe(now.getMonth()); 10 | }); 11 | 12 | it('will get the date tommorrow', function() { 13 | var now = easyDate(1).day().fromNow() 14 | var today = EasyDate.tomorrow(); 15 | expect(today.getDate()).toBe(now.getDate()); 16 | expect(today.getFullYear()).toBe(now.getFullYear()); 17 | expect(today.getMonth()).toBe(now.getMonth()); 18 | }); 19 | 20 | it('will get the date yesterday', function() { 21 | var now = easyDate(1).day().ago() 22 | var today = EasyDate.yesterday(); 23 | expect(today.getDate()).toBe(now.getDate()); 24 | expect(today.getFullYear()).toBe(now.getFullYear()); 25 | expect(today.getMonth()).toBe(now.getMonth()); 26 | }); 27 | }); 28 | -------------------------------------------------------------------------------- /test/easyDateClassSpec.js: -------------------------------------------------------------------------------- 1 | import { EasyDate } from '../easy-date' 2 | 3 | describe('EasyDate', () => { 4 | 5 | it('#getDate', () => { 6 | const date = new Date() 7 | const es = new EasyDate(date) 8 | expect(es.getDate()).toBe(date) 9 | }) 10 | 11 | it('#format', () => { 12 | const date = new Date("2018-01-01") 13 | const es = new EasyDate() 14 | expect(es.format("yyyy")).toBe("2018") 15 | }) 16 | }) 17 | -------------------------------------------------------------------------------- /test/easyDateFormatsLegacySpec.js: -------------------------------------------------------------------------------- 1 | import { backwardCompatibility } from '../easy-date' 2 | backwardCompatibility() 3 | 4 | describe('EasyDate Formats', function() { 5 | it('dates will have a default format function', function() { 6 | var now = new Date(2015, 11,1); 7 | expect(now.format()).toBe("Tue Dec 01 2015 00:00:00"); 8 | }); 9 | 10 | describe('#fromNow', function() { 11 | it('will return formatted date string if mask is passed', function () { 12 | var now = 2..days().fromNow(); 13 | expect(2..days().fromNow("yyyy")).toBe(now.getFullYear().toString()); 14 | }); 15 | it('will return the actual date object if now masked is passed', function() { 16 | var now = 2..days().fromNow(); 17 | expect(2..days().fromNow() instanceof Date).toBe(true); 18 | }); 19 | }); 20 | 21 | describe('#since', function() { 22 | it('will return formatted date string if mask is passed', function () { 23 | var now = 2..days().since(Date.now()); 24 | expect(2..days().since(Date.now(), "yyyy")).toBe(now.getFullYear().toString()); 25 | }); 26 | it('will return the actual date object if now masked is passed', function() { 27 | var now = 2..days().since(Date.now()); 28 | expect(2..days().since(Date.now()) instanceof Date).toBe(true); 29 | }); 30 | }); 31 | 32 | describe('#ago', function() { 33 | it('will return formatted date string if mask is passed', function () { 34 | var now = 2..days().ago(); 35 | expect(2..days().ago("yyyy")).toBe(now.getFullYear().toString()); 36 | }); 37 | it('will return the actual date object if now masked is passed', function() { 38 | var now = 2..days().ago(); 39 | expect(2..days().ago() instanceof Date).toBe(true); 40 | }); 41 | }); 42 | 43 | describe('#until', function() { 44 | it('will return formatted date string if mask is passed', function () { 45 | var now = 2..days().until(Date.today()); 46 | expect(2..days().until(Date.today(), "yyyy")).toBe(now.getFullYear().toString()); 47 | }); 48 | 49 | it('will return the actual date object if now masked is passed', function() { 50 | var now = 2..days().until(Date.today()); 51 | expect(2..days().until(Date.today()) instanceof Date).toBe(true); 52 | }); 53 | }); 54 | 55 | }); 56 | -------------------------------------------------------------------------------- /test/easyDateFormatsSpec.js: -------------------------------------------------------------------------------- 1 | import { easyDate, EasyDate } from '../easy-date' 2 | 3 | describe('EasyDate Formats', function() { 4 | it('dates will have a default format function', function() { 5 | var now = new Date(2015, 11,1); 6 | expect(now.format()).toBe("Tue Dec 01 2015 00:00:00"); 7 | }); 8 | 9 | describe('#fromNow', function() { 10 | it('will return formatted date string if mask is passed', function () { 11 | var now = easyDate(2).days().fromNow(); 12 | expect(easyDate(2).days().fromNow("yyyy")).toBe(now.getFullYear().toString()); 13 | }); 14 | it('will return the actual date object if now masked is passed', function() { 15 | var now = easyDate(2).days().fromNow(); 16 | expect(easyDate(2).days().fromNow() instanceof Date).toBe(true); 17 | }); 18 | }); 19 | 20 | describe('#since', function() { 21 | it('will return formatted date string if mask is passed', function () { 22 | var now = easyDate(2).days().since(Date.now()); 23 | expect(easyDate(2).days().since(Date.now(), "yyyy")).toBe(now.getFullYear().toString()); 24 | }); 25 | it('will return the actual date object if now masked is passed', function() { 26 | var now = easyDate(2).days().since(Date.now()); 27 | expect(easyDate(2).days().since(Date.now()) instanceof Date).toBe(true); 28 | }); 29 | }); 30 | 31 | describe('#ago', function() { 32 | it('will return formatted date string if mask is passed', function () { 33 | var now = easyDate(2).days().ago(); 34 | expect(easyDate(2).days().ago("yyyy")).toBe(now.getFullYear().toString()); 35 | }); 36 | it('will return the actual date object if now masked is passed', function() { 37 | var now = easyDate(2).days().ago(); 38 | expect(easyDate(2).days().ago() instanceof Date).toBe(true); 39 | }); 40 | }); 41 | 42 | describe('#until', function() { 43 | it('will return formatted date string if mask is passed', function () { 44 | var now = easyDate(2).days().until(EasyDate.today()); 45 | expect(easyDate(2).days().until(EasyDate.today(), "yyyy")).toBe(now.getFullYear().toString()); 46 | }); 47 | 48 | it('will return the actual date object if now masked is passed', function() { 49 | var now = easyDate(2).days().until(EasyDate.today()); 50 | expect(easyDate(2).days().until(EasyDate.today()) instanceof Date).toBe(true); 51 | }); 52 | }); 53 | 54 | }); 55 | -------------------------------------------------------------------------------- /test/easyDateLegacySpec.js: -------------------------------------------------------------------------------- 1 | import { backwardCompatibility } from '../easy-date' 2 | backwardCompatibility() 3 | 4 | describe('EasyDate with legacy syntax', function() { 5 | 6 | it('will return the correct date 5 days from now', function() { 7 | var now = new Date(); 8 | now.setDate(now.getDate() + 5); 9 | var newDate = 5..days().fromNow(); 10 | 11 | expect(newDate.getYear()).toBe(newDate.getYear()) 12 | expect(newDate.getMonth()).toBe(newDate.getMonth()) 13 | expect(newDate.getDate()).toBe(newDate.getDate()) 14 | }); 15 | 16 | it('will return the correct date 5 days ago', function() { 17 | var now = new Date(); 18 | now.setDate(now.getDate() - 5); 19 | var newDate = 5..days().ago(); 20 | 21 | expect(newDate.getYear()).toBe(newDate.getYear()) 22 | expect(newDate.getMonth()).toBe(newDate.getMonth()) 23 | expect(newDate.getDate()).toBe(newDate.getDate()) 24 | }); 25 | 26 | it('will return the correct date 5 months from now', function() { 27 | var now = new Date(); 28 | now.setMonth(now.getMonth() + 5); 29 | var newDate = 5..months().fromNow(); 30 | 31 | expect(newDate.getYear()).toBe(newDate.getYear()) 32 | expect(newDate.getMonth()).toBe(newDate.getMonth()) 33 | expect(newDate.getDate()).toBe(newDate.getDate()) 34 | }); 35 | 36 | it('will return the correct date 5 months ago', function() { 37 | var now = new Date(); 38 | now.setMonth(now.getMonth() - 5); 39 | var newDate = 5..months().ago(); 40 | 41 | expect(newDate.getYear()).toBe(newDate.getYear()) 42 | expect(newDate.getMonth()).toBe(newDate.getMonth()) 43 | expect(newDate.getDate()).toBe(newDate.getDate()) 44 | }); 45 | 46 | it('will return the correct date 5 years from now', function() { 47 | var now = new Date(); 48 | now.setFullYear(now.getFullYear() + 5); 49 | var newDate = 5..years().fromNow(); 50 | 51 | expect(newDate.getYear()).toBe(newDate.getYear()) 52 | expect(newDate.getMonth()).toBe(newDate.getMonth()) 53 | expect(newDate.getDate()).toBe(newDate.getDate()) 54 | }); 55 | 56 | it('will return the correct date 5 years ago', function() { 57 | var now = new Date(); 58 | now.setFullYear(now.getFullYear() - 5); 59 | var newDate = 5..years().ago(); 60 | 61 | expect(newDate.getYear()).toBe(newDate.getYear()) 62 | expect(newDate.getMonth()).toBe(newDate.getMonth()) 63 | expect(newDate.getDate()).toBe(newDate.getDate()) 64 | }); 65 | 66 | 67 | 68 | describe('#days', function() { 69 | it('can get the number of days', function() { 70 | expect(2..days().value).toBe(2); 71 | expect(1..day().conversionType).toBe("day"); 72 | }); 73 | 74 | it('will get the correct grammar', function() { 75 | expect(1..day().toString()).toBe("1 day"); 76 | expect(3..days().toString()).toBe("3 days"); 77 | expect(5..days().toString()).toBe("5 days"); 78 | }); 79 | 80 | it('#fromNow', function() { 81 | var now = new Date(); 82 | expect(3..days().fromNow().getDate()).toBe(now.getDate() + 3); 83 | }); 84 | 85 | it('#ago', function() { 86 | var now = new Date(); 87 | now.setDate(now.getDate() - 3); 88 | expect(3..days().ago().getDate()).toBe(now.getDate()); 89 | }); 90 | 91 | it('#since', function() { 92 | var now = new Date(2015, 3, 10); 93 | expect(3..days().since(now).getDate()).toBe(13); 94 | }); 95 | 96 | it('#until', function() { 97 | var now = new Date(2015, 3, 10); 98 | var newDate = now.getDate() - 3; 99 | expect(3..days().until(now).getDate()).toBe(newDate); 100 | }); 101 | 102 | it('#before', function() { 103 | var now = new Date(2015, 3, 10); 104 | var newDate = now.getDate() - 3; 105 | expect(3..days().before(now).getDate()).toBe(newDate); 106 | }); 107 | }); 108 | 109 | 110 | describe('#months', function() { 111 | it('can get the number of months', function() { 112 | expect(2..months().value).toBe(2); 113 | expect(1..month().conversionType).toBe("month"); 114 | }); 115 | 116 | it('will get the correct grammar', function() { 117 | expect(1..month().toString()).toBe("1 month"); 118 | expect(3..months().toString()).toBe("3 months"); 119 | expect(5..months().toString()).toBe("5 months"); 120 | }); 121 | 122 | it('#fromNow', function() { 123 | var now = new Date(); 124 | var res = now.getMonth() + 3; 125 | if (res > 11) { 126 | res = res - 12; 127 | } 128 | expect(3..months().fromNow().getMonth()).toBe(res); 129 | }); 130 | 131 | it('#ago', function() { 132 | var now = new Date(); 133 | var res = now.getMonth() - 3; 134 | if (res < 0) { 135 | res = res + 12; 136 | } 137 | expect(3..months().ago().getMonth()).toBe(res); 138 | }); 139 | 140 | it('#since', function() { 141 | var now = new Date(2015, 3, 10); 142 | expect(3..months().since(now).getMonth()).toBe(6); 143 | }); 144 | 145 | it('#until', function() { 146 | var now = new Date(2015, 9, 10); 147 | expect(3..months().until(now).getMonth()).toBe(6); 148 | }); 149 | 150 | it('#before', function() { 151 | var now = new Date(2015, 9, 10); 152 | expect(3..months().before(now).getMonth()).toBe(6); 153 | }); 154 | }); 155 | 156 | describe('#years', function() { 157 | it('can get the number of years', function() { 158 | expect(2..years().value).toBe(2); 159 | expect(1..year().conversionType).toBe("year"); 160 | }); 161 | 162 | it('will get the correct grammar', function() { 163 | expect(1..year().toString()).toBe("1 year"); 164 | expect(3..years().toString()).toBe("3 years"); 165 | expect(5..years().toString()).toBe("5 years"); 166 | }); 167 | 168 | it('#fromNow', function() { 169 | var now = new Date(); 170 | expect(3..years().fromNow().getFullYear()).toBe(now.getFullYear() + 3); 171 | }); 172 | 173 | it('#ago', function() { 174 | var now = new Date(); 175 | expect(3..years().ago().getFullYear()).toBe(now.getFullYear() - 3); 176 | }); 177 | 178 | it('#since', function() { 179 | var now = new Date(2015, 3, 10); 180 | expect(3..years().since(now).getFullYear()).toBe(2018); 181 | }); 182 | 183 | it('#until', function() { 184 | var now = new Date(2015, 9, 10); 185 | expect(3..years().until(now).getFullYear()).toBe(2012); 186 | }); 187 | 188 | it('#before', function() { 189 | var now = new Date(2015, 9, 10); 190 | expect(3..years().before(now).getFullYear()).toBe(2012); 191 | }); 192 | }); 193 | 194 | describe('#hours', function() { 195 | it('can get the number of hours', function() { 196 | expect(2..hours().value).toBe(2); 197 | expect(1..hour().conversionType).toBe("hour"); 198 | }); 199 | 200 | it('will get the correct grammar', function() { 201 | expect(1..hour().toString()).toBe("1 hour"); 202 | expect(3..hours().toString()).toBe("3 hours"); 203 | expect(5..hours().toString()).toBe("5 hours"); 204 | }); 205 | 206 | it('#fromNow', function() { 207 | var now = new Date(); 208 | now.setHours(now.getHours() + 3); 209 | expect(3..hours().fromNow().getHours()).toBe(now.getHours()); 210 | }); 211 | 212 | it('#ago', function() { 213 | var now = new Date(); 214 | now.setHours(now.getHours() - 3); 215 | expect(3..hours().ago().getHours()).toBe(now.getHours()); 216 | }); 217 | 218 | it('#since', function() { 219 | var now = new Date(2015, 3, 10, 12); 220 | expect(3..hours().since(now).getHours()).toBe(15); 221 | }); 222 | 223 | it('#until', function() { 224 | var now = new Date(2015, 9, 10, 12); 225 | expect(3..hours().until(now).getHours()).toBe(9); 226 | }); 227 | 228 | it('#before', function() { 229 | var now = new Date(2015, 9, 10, 12); 230 | expect(3..hours().before(now).getHours()).toBe(9); 231 | }); 232 | }); 233 | }); 234 | -------------------------------------------------------------------------------- /test/easyDateSpec.js: -------------------------------------------------------------------------------- 1 | import { easyDate } from '../easy-date' 2 | 3 | describe('easyDate', function() { 4 | 5 | it('will return the correct date 5 days from now', function() { 6 | var now = new Date(); 7 | now.setDate(now.getDate() + 5); 8 | var newDate = easyDate(5).days().fromNow(); 9 | 10 | expect(newDate.getYear()).toBe(newDate.getYear()) 11 | expect(newDate.getMonth()).toBe(newDate.getMonth()) 12 | expect(newDate.getDate()).toBe(newDate.getDate()) 13 | }); 14 | 15 | it('will return the correct date 5 days ago', function() { 16 | var now = new Date(); 17 | now.setDate(now.getDate() - 5); 18 | var newDate = easyDate(5).days().ago(); 19 | 20 | expect(newDate.getYear()).toBe(newDate.getYear()) 21 | expect(newDate.getMonth()).toBe(newDate.getMonth()) 22 | expect(newDate.getDate()).toBe(newDate.getDate()) 23 | }); 24 | 25 | it('will return the correct date 5 months from now', function() { 26 | var now = new Date(); 27 | now.setMonth(now.getMonth() + 5); 28 | var newDate = easyDate(5).months().fromNow(); 29 | 30 | expect(newDate.getYear()).toBe(newDate.getYear()) 31 | expect(newDate.getMonth()).toBe(newDate.getMonth()) 32 | expect(newDate.getDate()).toBe(newDate.getDate()) 33 | }); 34 | 35 | it('will return the correct date 5 months ago', function() { 36 | var now = new Date(); 37 | now.setMonth(now.getMonth() - 5); 38 | var newDate = easyDate(5).months().ago(); 39 | 40 | expect(newDate.getYear()).toBe(newDate.getYear()) 41 | expect(newDate.getMonth()).toBe(newDate.getMonth()) 42 | expect(newDate.getDate()).toBe(newDate.getDate()) 43 | }); 44 | 45 | it('will return the correct date 5 years from now', function() { 46 | var now = new Date(); 47 | now.setFullYear(now.getFullYear() + 5); 48 | var newDate = easyDate(5).years().fromNow(); 49 | 50 | expect(newDate.getYear()).toBe(newDate.getYear()) 51 | expect(newDate.getMonth()).toBe(newDate.getMonth()) 52 | expect(newDate.getDate()).toBe(newDate.getDate()) 53 | }); 54 | 55 | it('will return the correct date 5 years ago', function() { 56 | var now = new Date(); 57 | now.setFullYear(now.getFullYear() - 5); 58 | var newDate = easyDate(5).years().ago(); 59 | 60 | expect(newDate.getYear()).toBe(newDate.getYear()) 61 | expect(newDate.getMonth()).toBe(newDate.getMonth()) 62 | expect(newDate.getDate()).toBe(newDate.getDate()) 63 | }); 64 | 65 | 66 | 67 | describe('#days', function() { 68 | it('can get the number of days', function() { 69 | expect(easyDate(2).days().value).toBe(2); 70 | expect(easyDate(1).day().conversionType).toBe("day"); 71 | }); 72 | 73 | it('will get the correct grammar', function() { 74 | expect(easyDate(1).day().toString()).toBe("1 day"); 75 | expect(easyDate(3).days().toString()).toBe("3 days"); 76 | expect(easyDate(5).days().toString()).toBe("5 days"); 77 | }); 78 | 79 | it('#fromNow', function() { 80 | var now = new Date(); 81 | expect(easyDate(3).days().fromNow().getDate()).toBe(now.getDate() + 3); 82 | }); 83 | 84 | it('#ago', function() { 85 | var now = new Date(); 86 | now.setDate(now.getDate() - 3); 87 | expect(easyDate(3).days().ago().getDate()).toBe(now.getDate()); 88 | }); 89 | 90 | it('#since', function() { 91 | var now = new Date(2015, 3, 10); 92 | expect(easyDate(3).days().since(now).getDate()).toBe(13); 93 | }); 94 | 95 | it('#until', function() { 96 | var now = new Date(2015, 3, 10); 97 | var newDate = now.getDate() - 3; 98 | expect(easyDate(3).days().until(now).getDate()).toBe(newDate); 99 | }); 100 | 101 | it('#before', function() { 102 | var now = new Date(2015, 3, 10); 103 | var newDate = now.getDate() - 3; 104 | expect(easyDate(3).days().before(now).getDate()).toBe(newDate); 105 | }); 106 | }); 107 | 108 | 109 | describe('#months', function() { 110 | it('can get the number of months', function() { 111 | expect(easyDate(2).months().value).toBe(2); 112 | expect(easyDate(1).month().conversionType).toBe("month"); 113 | }); 114 | 115 | it('will get the correct grammar', function() { 116 | expect(easyDate(1).month().toString()).toBe("1 month"); 117 | expect(easyDate(3).months().toString()).toBe("3 months"); 118 | expect(easyDate(5).months().toString()).toBe("5 months"); 119 | }); 120 | 121 | it('#fromNow', function() { 122 | var now = new Date(); 123 | var res = now.getMonth() + 3; 124 | if (res > 11) { 125 | res = res - 12; 126 | } 127 | expect(easyDate(3).months().fromNow().getMonth()).toBe(res); 128 | }); 129 | 130 | it('#ago', function() { 131 | var now = new Date(); 132 | var res = now.getMonth() - 3; 133 | if (res < 0) { 134 | res = res + 12; 135 | } 136 | expect(easyDate(3).months().ago().getMonth()).toBe(res); 137 | }); 138 | 139 | it('#since', function() { 140 | var now = new Date(2015, 3, 10); 141 | expect(easyDate(3).months().since(now).getMonth()).toBe(6); 142 | }); 143 | 144 | it('#until', function() { 145 | var now = new Date(2015, 9, 10); 146 | expect(easyDate(3).months().until(now).getMonth()).toBe(6); 147 | }); 148 | 149 | it('#before', function() { 150 | var now = new Date(2015, 9, 10); 151 | expect(easyDate(3).months().before(now).getMonth()).toBe(6); 152 | }); 153 | }); 154 | 155 | describe('#years', function() { 156 | it('can get the number of years', function() { 157 | expect(easyDate(2).years().value).toBe(2); 158 | expect(easyDate(1).year().conversionType).toBe("year"); 159 | }); 160 | 161 | it('will get the correct grammar', function() { 162 | expect(easyDate(1).year().toString()).toBe("1 year"); 163 | expect(easyDate(3).years().toString()).toBe("3 years"); 164 | expect(easyDate(5).years().toString()).toBe("5 years"); 165 | }); 166 | 167 | it('#fromNow', function() { 168 | var now = new Date(); 169 | expect(easyDate(3).years().fromNow().getFullYear()).toBe(now.getFullYear() + 3); 170 | }); 171 | 172 | it('#ago', function() { 173 | var now = new Date(); 174 | expect(easyDate(3).years().ago().getFullYear()).toBe(now.getFullYear() - 3); 175 | }); 176 | 177 | it('#since', function() { 178 | var now = new Date(2015, 3, 10); 179 | expect(easyDate(3).years().since(now).getFullYear()).toBe(2018); 180 | }); 181 | 182 | it('#until', function() { 183 | var now = new Date(2015, 9, 10); 184 | expect(easyDate(3).years().until(now).getFullYear()).toBe(2012); 185 | }); 186 | 187 | it('#before', function() { 188 | var now = new Date(2015, 9, 10); 189 | expect(easyDate(3).years().before(now).getFullYear()).toBe(2012); 190 | }); 191 | }); 192 | 193 | describe('#hours', function() { 194 | it('can get the number of hours', function() { 195 | expect(easyDate(2).hours().value).toBe(2); 196 | expect(easyDate(1).hour().conversionType).toBe("hour"); 197 | }); 198 | 199 | it('will get the correct grammar', function() { 200 | expect(easyDate(1).hour().toString()).toBe("1 hour"); 201 | expect(easyDate(3).hours().toString()).toBe("3 hours"); 202 | expect(easyDate(5).hours().toString()).toBe("5 hours"); 203 | }); 204 | 205 | it('#fromNow', function() { 206 | var now = new Date(); 207 | now.setHours(now.getHours() + 3); 208 | expect(easyDate(3).hours().fromNow().getHours()).toBe(now.getHours()); 209 | }); 210 | 211 | it('#ago', function() { 212 | var now = new Date(); 213 | now.setHours(now.getHours() - 3); 214 | expect(easyDate(3).hours().ago().getHours()).toBe(now.getHours()); 215 | }); 216 | 217 | it('#since', function() { 218 | var now = new Date(2015, 3, 10, 12); 219 | expect(easyDate(3).hours().since(now).getHours()).toBe(15); 220 | }); 221 | 222 | it('#until', function() { 223 | var now = new Date(2015, 9, 10, 12); 224 | expect(easyDate(3).hours().until(now).getHours()).toBe(9); 225 | }); 226 | 227 | it('#before', function() { 228 | var now = new Date(2015, 9, 10, 12); 229 | expect(easyDate(3).hours().before(now).getHours()).toBe(9); 230 | }); 231 | }); 232 | 233 | describe('#minutes', function() { 234 | it('can get the number of minutes', function() { 235 | expect(easyDate(2).minutes().value).toBe(2); 236 | expect(easyDate(1).minutes().conversionType).toBe("minute"); 237 | }); 238 | 239 | it('will get the correct grammar', function() { 240 | expect(easyDate(1).minute().toString()).toBe("1 minute"); 241 | expect(easyDate(3).minutes().toString()).toBe("3 minutes"); 242 | expect(easyDate(5).minutes().toString()).toBe("5 minutes"); 243 | }); 244 | 245 | it('#fromNow', function() { 246 | var now = new Date(); 247 | now.setMinutes(now.getMinutes() + 3); 248 | expect(easyDate(3).minutes().fromNow().getMinutes()).toBe(now.getMinutes()); 249 | }); 250 | 251 | it('#ago', function() { 252 | var now = new Date(); 253 | now.setMinutes(now.getMinutes() - 3); 254 | expect(easyDate(3).minutes().ago().getMinutes()).toBe(now.getMinutes()); 255 | }); 256 | 257 | it('#since', function() { 258 | var now = new Date(2015, 3, 10, 12, 5); 259 | expect(easyDate(3).minutes().since(now).getMinutes()).toBe(8); 260 | }); 261 | 262 | it('#until', function() { 263 | var now = new Date(2015, 9, 10, 12, 5); 264 | expect(easyDate(3).minutes().until(now).getMinutes()).toBe(2); 265 | }); 266 | 267 | it('#before', function() { 268 | var now = new Date(2015, 9, 10, 12, 5); 269 | expect(easyDate(3).minutes().before(now).getMinutes()).toBe(2); 270 | }); 271 | }); 272 | 273 | }); 274 | -------------------------------------------------------------------------------- /test/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Easy Date Test Runner 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | -------------------------------------------------------------------------------- /webpack.config.dev.js: -------------------------------------------------------------------------------- 1 | var webpack = require('webpack'); 2 | const merge = require('webpack-merge') 3 | 4 | const common = require('./webpack.config.js') 5 | 6 | module.exports = merge(common, { 7 | mode: 'development' 8 | 9 | }) 10 | -------------------------------------------------------------------------------- /webpack.config.js: -------------------------------------------------------------------------------- 1 | var path = require('path'); 2 | var webpack = require('webpack'); 3 | 4 | module.exports = { 5 | entry: { 6 | 'easy-date-light': ['./src/easy-date.js'], 7 | 'easy-date': ['./src/bundled.js'] 8 | }, 9 | output: { 10 | filename: '[name].js', 11 | path: path.resolve(__dirname, './'), 12 | libraryTarget: 'umd' 13 | }, 14 | 15 | module: { 16 | rules: [ 17 | { 18 | test: /\.(js)$/, 19 | exclude: /node_modules/, 20 | use: ['babel-loader'] 21 | } 22 | ] 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /webpack.config.prod.js: -------------------------------------------------------------------------------- 1 | var path = require('path'); 2 | var webpack = require('webpack'); 3 | const merge = require('webpack-merge') 4 | const common = require('./webpack.config.js') 5 | const UglifyJSPlugin = require('uglifyjs-webpack-plugin') 6 | 7 | var uglifyJs = new UglifyJSPlugin(); 8 | 9 | module.exports = merge(common, { 10 | mode: 'production', 11 | output: { 12 | filename: '[name].min.js', 13 | path: path.resolve(__dirname, './') 14 | }, 15 | plugins: [ 16 | uglifyJs 17 | ] 18 | }) 19 | --------------------------------------------------------------------------------