datemath.ts 2.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111
  1. ///<reference path="../../headers/common.d.ts" />
  2. import _ = require('lodash');
  3. import moment = require('moment');
  4. var units = ['y', 'M', 'w', 'd', 'h', 'm', 's'];
  5. var unitsAsc = _.sortBy(units, function (unit) {
  6. return moment.duration(1, unit).valueOf();
  7. });
  8. var unitsDesc = unitsAsc.reverse();
  9. function parse(text, roundUp?) {
  10. if (!text) { return undefined; }
  11. if (moment.isMoment(text)) { return text; }
  12. if (_.isDate(text)) { return moment(text); }
  13. var time;
  14. var mathString = '';
  15. var index;
  16. var parseString;
  17. if (text.substring(0, 3) === 'now') {
  18. time = moment();
  19. mathString = text.substring('now'.length);
  20. } else {
  21. index = text.indexOf('||');
  22. if (index === -1) {
  23. parseString = text;
  24. mathString = ''; // nothing else
  25. } else {
  26. parseString = text.substring(0, index);
  27. mathString = text.substring(index + 2);
  28. }
  29. // We're going to just require ISO8601 timestamps, k?
  30. time = moment(parseString);
  31. }
  32. if (!mathString.length) {
  33. return time;
  34. }
  35. return parseDateMath(mathString, time, roundUp);
  36. }
  37. function parseDateMath(mathString, time, roundUp?) {
  38. var dateTime = time;
  39. var i = 0;
  40. var len = mathString.length;
  41. while (i < len) {
  42. var c = mathString.charAt(i++);
  43. var type;
  44. var num;
  45. var unit;
  46. if (c === '/') {
  47. type = 0;
  48. } else if (c === '+') {
  49. type = 1;
  50. } else if (c === '-') {
  51. type = 2;
  52. } else {
  53. return undefined;
  54. }
  55. if (isNaN(mathString.charAt(i))) {
  56. num = 1;
  57. } else if (mathString.length === 2) {
  58. num = mathString.charAt(i);
  59. } else {
  60. var numFrom = i;
  61. while (!isNaN(mathString.charAt(i))) {
  62. i++;
  63. if (i > 10) { return undefined; }
  64. }
  65. num = parseInt(mathString.substring(numFrom, i), 10);
  66. }
  67. if (type === 0) {
  68. // rounding is only allowed on whole, single, units (eg M or 1M, not 0.5M or 2M)
  69. if (num !== 1) {
  70. return undefined;
  71. }
  72. }
  73. unit = mathString.charAt(i++);
  74. if (!_.contains(units, unit)) {
  75. return undefined;
  76. } else {
  77. if (type === 0) {
  78. if (roundUp) {
  79. dateTime.endOf(unit);
  80. }
  81. else {
  82. dateTime.startOf(unit);
  83. }
  84. } else if (type === 1) {
  85. dateTime.add(num, unit);
  86. } else if (type === 2) {
  87. dateTime.subtract(num, unit);
  88. }
  89. }
  90. }
  91. return dateTime;
  92. }
  93. export = {
  94. parse: parse,
  95. parseDateMath: parseDateMath
  96. };