forked from git.gladyson/openmonetis
- Replace ESLint with Biome for linting and formatting - Configure Biome with tabs, double quotes, and organized imports - Move all SQL/Drizzle queries from page.tsx files to data.ts files - Create new data.ts files for: ajustes, dashboard, relatorios/categorias - Update existing data.ts files: extrato, fatura (add lancamentos queries) - Remove all drizzle-orm imports from page.tsx files - Update README.md with new tooling info Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
251 lines
6.4 KiB
TypeScript
251 lines
6.4 KiB
TypeScript
/**
|
|
* Date utilities - Functions for date manipulation and formatting
|
|
*
|
|
* This module consolidates date-related utilities from:
|
|
* - /lib/utils/date.ts (basic date manipulation)
|
|
* - /lib/date/index.ts (formatting and display)
|
|
*
|
|
* Note: Period-related functions (YYYY-MM) are in /lib/utils/period
|
|
*/
|
|
|
|
// ============================================================================
|
|
// CONSTANTS
|
|
// ============================================================================
|
|
|
|
const WEEKDAY_NAMES = [
|
|
"Domingo",
|
|
"Segunda",
|
|
"Terça",
|
|
"Quarta",
|
|
"Quinta",
|
|
"Sexta",
|
|
"Sábado",
|
|
] as const;
|
|
|
|
const MONTH_NAMES = [
|
|
"janeiro",
|
|
"fevereiro",
|
|
"março",
|
|
"abril",
|
|
"maio",
|
|
"junho",
|
|
"julho",
|
|
"agosto",
|
|
"setembro",
|
|
"outubro",
|
|
"novembro",
|
|
"dezembro",
|
|
] as const;
|
|
|
|
// ============================================================================
|
|
// DATE CREATION & MANIPULATION
|
|
// ============================================================================
|
|
|
|
/**
|
|
* Safely parses a date string (YYYY-MM-DD) as a local date
|
|
*
|
|
* IMPORTANT: new Date("2025-11-25") treats the date as UTC midnight,
|
|
* which in Brazil (UTC-3) becomes 2025-11-26 03:00 local time!
|
|
*
|
|
* This function always interprets the date string in the local timezone.
|
|
*
|
|
* @param dateString - Date string in YYYY-MM-DD format
|
|
* @returns Date object in local timezone
|
|
*/
|
|
export function parseLocalDateString(dateString: string): Date {
|
|
const [year, month, day] = dateString.split("-");
|
|
return new Date(
|
|
Number.parseInt(year ?? "0", 10),
|
|
Number.parseInt(month ?? "1", 10) - 1,
|
|
Number.parseInt(day ?? "1", 10),
|
|
);
|
|
}
|
|
|
|
/**
|
|
* Gets today's date in UTC
|
|
* @returns Date object set to today at midnight UTC
|
|
*/
|
|
export function getTodayUTC(): Date {
|
|
const now = new Date();
|
|
const year = now.getUTCFullYear();
|
|
const month = now.getUTCMonth();
|
|
const day = now.getUTCDate();
|
|
|
|
return new Date(Date.UTC(year, month, day));
|
|
}
|
|
|
|
/**
|
|
* Gets today's date in local timezone
|
|
* @returns Date object set to today at midnight local time
|
|
*/
|
|
export function getTodayLocal(): Date {
|
|
const now = new Date();
|
|
const year = now.getFullYear();
|
|
const month = now.getMonth();
|
|
const day = now.getDate();
|
|
|
|
return new Date(year, month, day);
|
|
}
|
|
|
|
/**
|
|
* Gets today's period in YYYY-MM format (UTC)
|
|
* @returns Period string
|
|
*/
|
|
export function getTodayPeriodUTC(): string {
|
|
const now = new Date();
|
|
const year = now.getUTCFullYear();
|
|
const month = now.getUTCMonth();
|
|
|
|
return `${year}-${String(month + 1).padStart(2, "0")}`;
|
|
}
|
|
|
|
/**
|
|
* Formats date as YYYY-MM-DD string
|
|
* @param date - Date to format
|
|
* @returns Formatted date string
|
|
*/
|
|
export function formatDateForDb(date: Date): string {
|
|
const year = date.getFullYear();
|
|
const month = String(date.getMonth() + 1).padStart(2, "0");
|
|
const day = String(date.getDate()).padStart(2, "0");
|
|
|
|
return `${year}-${month}-${day}`;
|
|
}
|
|
|
|
/**
|
|
* Gets today's date as YYYY-MM-DD string
|
|
* @returns Formatted date string
|
|
*/
|
|
export function getTodayDateString(): string {
|
|
const now = new Date();
|
|
const year = now.getFullYear();
|
|
const month = String(now.getMonth() + 1).padStart(2, "0");
|
|
const day = String(now.getDate()).padStart(2, "0");
|
|
|
|
return `${year}-${month}-${day}`;
|
|
}
|
|
|
|
/**
|
|
* Gets today's date as Date object
|
|
* @returns Date object for today
|
|
*/
|
|
export function getTodayDate(): Date {
|
|
return parseLocalDateString(getTodayDateString());
|
|
}
|
|
|
|
/**
|
|
* Gets today's info (date and period)
|
|
* @returns Object with date and period
|
|
*/
|
|
export function getTodayInfo(): { date: Date; period: string } {
|
|
const now = new Date();
|
|
const year = now.getFullYear();
|
|
const month = now.getMonth();
|
|
const day = now.getDate();
|
|
|
|
return {
|
|
date: new Date(year, month, day),
|
|
period: `${year}-${String(month + 1).padStart(2, "0")}`,
|
|
};
|
|
}
|
|
|
|
/**
|
|
* Adds months to a date
|
|
* @param value - Date to add months to
|
|
* @param offset - Number of months to add (can be negative)
|
|
* @returns New date with months added
|
|
*/
|
|
export function addMonthsToDate(value: Date, offset: number): Date {
|
|
const result = new Date(value);
|
|
const originalDay = result.getDate();
|
|
|
|
result.setDate(1);
|
|
result.setMonth(result.getMonth() + offset);
|
|
|
|
const lastDay = new Date(
|
|
result.getFullYear(),
|
|
result.getMonth() + 1,
|
|
0,
|
|
).getDate();
|
|
|
|
result.setDate(Math.min(originalDay, lastDay));
|
|
return result;
|
|
}
|
|
|
|
// ============================================================================
|
|
// DATE FORMATTING
|
|
// ============================================================================
|
|
|
|
/**
|
|
* Formats a date string (YYYY-MM-DD) to short display format
|
|
* @example
|
|
* formatDate("2024-11-14") // "qui 14 nov"
|
|
*/
|
|
export function formatDate(value: string): string {
|
|
const parsed = parseLocalDateString(value);
|
|
|
|
return new Intl.DateTimeFormat("pt-BR", {
|
|
weekday: "short",
|
|
day: "2-digit",
|
|
month: "short",
|
|
})
|
|
.format(parsed)
|
|
.replace(".", "")
|
|
.replace(" de", "");
|
|
}
|
|
|
|
/**
|
|
* Formats a date to friendly long format
|
|
* @example
|
|
* friendlyDate(new Date()) // "Segunda, 14 de novembro de 2025"
|
|
*/
|
|
export function friendlyDate(date: Date): string {
|
|
const weekday = WEEKDAY_NAMES[date.getDay()];
|
|
const day = date.getDate();
|
|
const month = MONTH_NAMES[date.getMonth()];
|
|
const year = date.getFullYear();
|
|
|
|
return `${weekday}, ${day} de ${month} de ${year}`;
|
|
}
|
|
|
|
// ============================================================================
|
|
// TIME-BASED UTILITIES
|
|
// ============================================================================
|
|
|
|
/**
|
|
* Gets appropriate greeting based on time of day
|
|
* @param date - Date to get greeting for (defaults to now)
|
|
* @returns "Bom dia", "Boa tarde", or "Boa noite"
|
|
*/
|
|
export function getGreeting(date: Date = new Date()): string {
|
|
const hour = date.getHours();
|
|
if (hour >= 5 && hour < 12) return "Bom dia";
|
|
if (hour >= 12 && hour < 18) return "Boa tarde";
|
|
return "Boa noite";
|
|
}
|
|
|
|
// ============================================================================
|
|
// DATE INFORMATION
|
|
// ============================================================================
|
|
|
|
/**
|
|
* Gets information about a date
|
|
* @param date - Date to analyze (defaults to now)
|
|
* @returns Object with date information
|
|
*/
|
|
export function getDateInfo(date: Date = new Date()) {
|
|
return {
|
|
date,
|
|
year: date.getFullYear(),
|
|
month: date.getMonth() + 1,
|
|
monthName: MONTH_NAMES[date.getMonth()],
|
|
day: date.getDate(),
|
|
weekday: WEEKDAY_NAMES[date.getDay()],
|
|
friendlyDisplay: friendlyDate(date),
|
|
greeting: getGreeting(date),
|
|
};
|
|
}
|
|
|
|
// Re-export MONTH_NAMES for convenience
|
|
export { MONTH_NAMES };
|