datemath.ts 2.5 KB

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