Loggest thine Stuff
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

117 lines
4.4 KiB

2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
  1. import type { TimeInterval } from "../models/common";
  2. import { addDays, addMonths, addYears, formatDate, startOfDay, startOfMonth, startOfWeek, startOfYear } from "./date";
  3. export default function parseInterval(s: string, date: Date): TimeInterval<Date> {
  4. const [verb, args] = s.split(":")
  5. switch (verb) {
  6. case "":
  7. case "all_time":
  8. return null;
  9. case "next": {
  10. const [amount, unit] = unitNumber(args);
  11. switch (unit) {
  12. case "d": case "days":
  13. return {display: "days", min: startOfDay(date), max: startOfDay(addDays(date, amount))}
  14. case "w": case "weeks":
  15. return {display: "days", min: startOfDay(date), max: startOfDay(addDays(date, amount * 7))}
  16. case "m": case "months":
  17. return {display: "days", min: startOfDay(date), max: startOfDay(addMonths(date, amount))}
  18. case "y": case "years":
  19. return {display: "none", min: startOfDay(date), max: startOfDay(addYears(date, amount))}
  20. }
  21. }
  22. case "last": {
  23. const [amount, unit] = unitNumber(args);
  24. switch (unit) {
  25. case "d": case "days":
  26. return {display: "days", min: startOfDay(addDays(date, -amount)), max: startOfDay(addDays(date, 1))}
  27. case "w": case "weeks":
  28. return {display: "weeks", min: startOfDay(addDays(date, -amount * 7)), max: startOfDay(addDays(date, 1))}
  29. case "m": case "months":
  30. return {display: "days", min: startOfDay(addMonths(date, -amount)), max: startOfDay(addDays(date, 1))}
  31. case "y": case "years":
  32. return {display: "none", min: startOfDay(addYears(date, -amount)), max: startOfDay(addDays(date, 1))}
  33. }
  34. }
  35. case "today":
  36. return {display: "none", min: startOfDay(date), max: startOfDay(addDays(date, 1))}
  37. case "next_week":
  38. return {display: "weeks", min: startOfWeek(addDays(date, 7)), max: startOfWeek(addDays(date, 14))}
  39. case "this_week":
  40. return {display: "weeks", min: startOfWeek(date), max: startOfWeek(addDays(date, 7))}
  41. case "last_week":
  42. return {display: "weeks", min: startOfWeek(addDays(date, -7)), max: startOfWeek(date)}
  43. case "next_month":
  44. return {display: "month", min: startOfMonth(addMonths(date, 1)), max: startOfMonth(addMonths(date, 2))}
  45. case "this_month":
  46. return {display: "month", min: startOfMonth(date), max: startOfMonth(addMonths(date, 1))}
  47. case "last_month":
  48. return {display: "month", min: startOfMonth(addMonths(date, -1)), max: startOfMonth(date)}
  49. case "next_year":
  50. return {display: "year", min: startOfYear(addYears(date, 1)), max: startOfYear(addYears(date, 2))}
  51. case "this_year":
  52. return {display: "year", min: startOfYear(date), max: startOfYear(addYears(date, 1))}
  53. case "last_year":
  54. return {display: "year", min: startOfYear(addYears(date, -1)), max: startOfYear(date)}
  55. }
  56. }
  57. export function intervalLabel(s: string): string {
  58. const [verb, args] = s.split(":")
  59. switch (verb) {
  60. case "":
  61. return "All time";
  62. case "next":
  63. case "last": {
  64. const [amount, unit] = unitNumber(args);
  65. switch (unit) {
  66. case "d": case "days":
  67. return `${capitalize(verb)} ${amount} ${amount !== 1 ? "days" : "day"}`
  68. case "w": case "weeks":
  69. return `${capitalize(verb)} ${amount} ${amount !== 1 ? "weeks" : "week"}`
  70. case "m": case "months":
  71. return `${capitalize(verb)} ${amount} ${amount !== 1 ? "months" : "month"}`
  72. case "y": case "years":
  73. return `${capitalize(verb)} ${amount} ${amount !== 1 ? "years" : "year"}`
  74. }
  75. }
  76. case "today":
  77. return verb;
  78. case "all_time":
  79. case "next_week":
  80. case "this_week":
  81. case "last_week":
  82. case "next_month":
  83. case "this_month":
  84. case "last_month":
  85. case "next_year":
  86. case "this_year":
  87. case "last_year":
  88. return capitalize(verb.replace("_", " "));
  89. }
  90. }
  91. export function datesOf(interval: TimeInterval<string | Date>): TimeInterval<string> {
  92. if (interval == null) {
  93. return void(0)
  94. }
  95. return {min: formatDate(interval.min), max: formatDate(interval.max)}
  96. }
  97. function capitalize(s: string) {
  98. return `${s.charAt(0).toLocaleUpperCase()}${s.slice(1)}`
  99. }
  100. function unitNumber(s: string): [number, string] {
  101. for (let i = 0; i < s.length; ++i) {
  102. const ch = s.charAt(i);
  103. if (ch < '0' || ch > '9') {
  104. return [parseInt(s.slice(0, i)), s.slice(i)]
  105. }
  106. }
  107. return [parseInt(s), ""];
  108. }