data.js 3.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596
  1. // Formatadores criados uma única vez: instanciar um Intl.DateTimeFormat custa ~10-40µs e
  2. // estas funções são chamadas dentro de v-for que repinta a cada poll.
  3. const FMT_DATA = new Intl.DateTimeFormat("pt-BR", { day: "2-digit", month: "2-digit", year: "numeric" });
  4. const FMT_HORA = new Intl.DateTimeFormat("pt-BR", { hour: "2-digit", minute: "2-digit" });
  5. const FMT_DIA_MES = new Intl.DateTimeFormat("pt-BR", { day: "2-digit", month: "2-digit" });
  6. const FMT_DATA_HORA = new Intl.DateTimeFormat("pt-BR", {
  7. day: "2-digit", month: "2-digit", year: "numeric", hour: "2-digit", minute: "2-digit"
  8. });
  9. // ano com 2 dígitos: usado na lista de documentos, onde o espaço é apertado
  10. const FMT_DATA_HORA_ANO_CURTO = new Intl.DateTimeFormat("pt-BR", {
  11. day: "2-digit", month: "2-digit", year: "2-digit", hour: "2-digit", minute: "2-digit"
  12. });
  13. // sem ano: usado nas solicitações de reset de senha, todas recentes
  14. const FMT_DATA_HORA_SEM_ANO = new Intl.DateTimeFormat("pt-BR", {
  15. day: "2-digit", month: "2-digit", hour: "2-digit", minute: "2-digit"
  16. });
  17. const UM_DIA_MS = 86400000;
  18. function paraData(valor) {
  19. if (!valor) return null;
  20. const d = new Date(valor);
  21. return Number.isNaN(d.getTime()) ? null : d;
  22. }
  23. function formatarCom(fmt, valor) {
  24. const d = paraData(valor);
  25. return d ? fmt.format(d) : "";
  26. }
  27. export function formatarData(valor) {
  28. return formatarCom(FMT_DATA, valor);
  29. }
  30. export function formatarHora(valor) {
  31. return formatarCom(FMT_HORA, valor);
  32. }
  33. export function formatarDataHora(valor) {
  34. return formatarCom(FMT_DATA_HORA, valor);
  35. }
  36. export function formatarDataHoraAnoCurto(valor) {
  37. return formatarCom(FMT_DATA_HORA_ANO_CURTO, valor);
  38. }
  39. export function formatarDataHoraSemAno(valor) {
  40. return formatarCom(FMT_DATA_HORA_SEM_ANO, valor);
  41. }
  42. export function ehNovoDia(atual, anterior) {
  43. if (!atual) return false;
  44. if (!anterior) return true;
  45. return new Date(atual).toDateString() !== new Date(anterior).toDateString();
  46. }
  47. // rótulo curto de recência para listas de conversa: hora se for hoje, "Ontem", senão dd/mm
  48. export function formatarRecencia(valor) {
  49. const d = paraData(valor);
  50. if (!d) return "";
  51. const hoje = new Date().setHours(0, 0, 0, 0);
  52. const dia = new Date(d).setHours(0, 0, 0, 0);
  53. if (dia === hoje) return FMT_HORA.format(d);
  54. if (dia === hoje - UM_DIA_MS) return "Ontem";
  55. return FMT_DIA_MES.format(d);
  56. }
  57. /**
  58. * Agrupa uma lista em faixas de recência ("Hoje", "Ontem", "Últimos 7 dias", "Mais antigas"),
  59. * descartando as faixas vazias. Usado pela lista de conversas do chat e pela do WhatsApp.
  60. *
  61. * @param {Array} lista
  62. * @param {(item: any) => number|string|Date|null} obterTimestamp
  63. */
  64. export function agruparPorRecencia(lista, obterTimestamp) {
  65. const hoje = new Date().setHours(0, 0, 0, 0);
  66. const ontem = hoje - UM_DIA_MS;
  67. const semana = hoje - 6 * UM_DIA_MS;
  68. const grupos = [
  69. { label: "Hoje", items: [] },
  70. { label: "Ontem", items: [] },
  71. { label: "Últimos 7 dias", items: [] },
  72. { label: "Mais antigas", items: [] }
  73. ];
  74. for (const item of lista ?? []) {
  75. const bruto = obterTimestamp(item);
  76. const t = bruto ? new Date(bruto).getTime() : 0;
  77. if (t >= hoje) grupos[0].items.push(item);
  78. else if (t >= ontem) grupos[1].items.push(item);
  79. else if (t >= semana) grupos[2].items.push(item);
  80. else grupos[3].items.push(item);
  81. }
  82. return grupos.filter((g) => g.items.length > 0);
  83. }