index.ts 5.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186
  1. export interface TimeDelta {
  2. hours?: number;
  3. days?: number;
  4. months?: number;
  5. years?: number;
  6. }
  7. interface DateComponent<T = number> {
  8. year: T;
  9. month: T;
  10. day: T;
  11. hour: T;
  12. minute: T;
  13. second: T;
  14. }
  15. const currentYear = new Date().getFullYear();
  16. export function getUnixTimeInMicroSecondsWithDelta(delta: TimeDelta): number {
  17. let currentDate = new Date();
  18. if (delta?.hours) {
  19. currentDate = _addHours(currentDate, delta.hours);
  20. }
  21. if (delta?.days) {
  22. currentDate = _addDays(currentDate, delta.days);
  23. }
  24. if (delta?.months) {
  25. currentDate = _addMonth(currentDate, delta.months);
  26. }
  27. if (delta?.years) {
  28. currentDate = _addYears(currentDate, delta.years);
  29. }
  30. return currentDate.getTime() * 1000;
  31. }
  32. export function validateAndGetCreationUnixTimeInMicroSeconds(dateTime: Date) {
  33. if (!dateTime || isNaN(dateTime.getTime())) {
  34. return null;
  35. }
  36. const unixTime = dateTime.getTime() * 1000;
  37. //ignoring dateTimeString = "0000:00:00 00:00:00"
  38. if (unixTime === Date.UTC(0, 0, 0, 0, 0, 0, 0) || unixTime === 0) {
  39. return null;
  40. } else if (unixTime > Date.now() * 1000) {
  41. return null;
  42. } else {
  43. return unixTime;
  44. }
  45. }
  46. function _addDays(date: Date, days: number): Date {
  47. const result = new Date(date);
  48. result.setDate(date.getDate() + days);
  49. return result;
  50. }
  51. function _addHours(date: Date, hours: number): Date {
  52. const result = new Date(date);
  53. result.setHours(date.getHours() + hours);
  54. return result;
  55. }
  56. function _addMonth(date: Date, months: number) {
  57. const result = new Date(date);
  58. result.setMonth(date.getMonth() + months);
  59. return result;
  60. }
  61. function _addYears(date: Date, years: number) {
  62. const result = new Date(date);
  63. result.setFullYear(date.getFullYear() + years);
  64. return result;
  65. }
  66. /*
  67. generates data component for date in format YYYYMMDD-HHMMSS
  68. */
  69. export function parseDateFromFusedDateString(dateTime: string) {
  70. const dateComponent: DateComponent<number> = convertDateComponentToNumber({
  71. year: dateTime.slice(0, 4),
  72. month: dateTime.slice(4, 6),
  73. day: dateTime.slice(6, 8),
  74. hour: dateTime.slice(9, 11),
  75. minute: dateTime.slice(11, 13),
  76. second: dateTime.slice(13, 15),
  77. });
  78. return validateAndGetDateFromComponents(dateComponent);
  79. }
  80. /* sample date format = 2018-08-19 12:34:45
  81. the date has six symbol separated number values
  82. which we would extract and use to form the date
  83. */
  84. export function tryToParseDateTime(dateTime: string): Date {
  85. const dateComponent = getDateComponentsFromSymbolJoinedString(dateTime);
  86. if (dateComponent.year?.length === 8 && dateComponent.month?.length === 6) {
  87. // the filename has size 8 consecutive and then 6 consecutive digits
  88. // high possibility that the it is a date in format YYYYMMDD-HHMMSS
  89. const possibleDateTime = dateComponent.year + "-" + dateComponent.month;
  90. return parseDateFromFusedDateString(possibleDateTime);
  91. }
  92. return validateAndGetDateFromComponents(
  93. convertDateComponentToNumber(dateComponent),
  94. );
  95. }
  96. function getDateComponentsFromSymbolJoinedString(
  97. dateTime: string,
  98. ): DateComponent<string> {
  99. const [year, month, day, hour, minute, second] =
  100. dateTime.match(/\d+/g) ?? [];
  101. return { year, month, day, hour, minute, second };
  102. }
  103. function validateAndGetDateFromComponents(
  104. dateComponent: DateComponent<number>,
  105. options = { minYear: 1990, maxYear: currentYear + 1 },
  106. ) {
  107. let date = getDateFromComponents(dateComponent);
  108. if (hasTimeValues(dateComponent) && !isTimePartValid(date, dateComponent)) {
  109. // if the date has time values but they are not valid
  110. // then we remove the time values and try to validate the date
  111. date = getDateFromComponents(removeTimeValues(dateComponent));
  112. }
  113. if (!isDatePartValid(date, dateComponent)) {
  114. return null;
  115. }
  116. if (
  117. date.getFullYear() < options.minYear ||
  118. date.getFullYear() > options.maxYear
  119. ) {
  120. return null;
  121. }
  122. return date;
  123. }
  124. function isTimePartValid(date: Date, dateComponent: DateComponent<number>) {
  125. return (
  126. date.getHours() === dateComponent.hour &&
  127. date.getMinutes() === dateComponent.minute &&
  128. date.getSeconds() === dateComponent.second
  129. );
  130. }
  131. function isDatePartValid(date: Date, dateComponent: DateComponent<number>) {
  132. return (
  133. date.getFullYear() === dateComponent.year &&
  134. date.getMonth() === dateComponent.month &&
  135. date.getDate() === dateComponent.day
  136. );
  137. }
  138. function convertDateComponentToNumber(
  139. dateComponent: DateComponent<string>,
  140. ): DateComponent<number> {
  141. return {
  142. year: Number(dateComponent.year),
  143. // https://stackoverflow.com/questions/2552483/why-does-the-month-argument-range-from-0-to-11-in-javascripts-date-constructor
  144. month: Number(dateComponent.month) - 1,
  145. day: Number(dateComponent.day),
  146. hour: Number(dateComponent.hour),
  147. minute: Number(dateComponent.minute),
  148. second: Number(dateComponent.second),
  149. };
  150. }
  151. function getDateFromComponents(dateComponent: DateComponent<number>) {
  152. const { year, month, day, hour, minute, second } = dateComponent;
  153. if (hasTimeValues(dateComponent)) {
  154. return new Date(year, month, day, hour, minute, second);
  155. } else {
  156. return new Date(year, month, day);
  157. }
  158. }
  159. function hasTimeValues(dateComponent: DateComponent<number>) {
  160. const { hour, minute, second } = dateComponent;
  161. return !isNaN(hour) && !isNaN(minute) && !isNaN(second);
  162. }
  163. function removeTimeValues(
  164. dateComponent: DateComponent<number>,
  165. ): DateComponent<number> {
  166. return { ...dateComponent, hour: 0, minute: 0, second: 0 };
  167. }