feat: enhance date handling and formatting in quotes and belo features

This commit is contained in:
Jose Selesan
2026-06-04 11:32:38 -03:00
parent 7c864053bb
commit 0915ad1223
7 changed files with 29 additions and 26 deletions

View File

@@ -8,3 +8,13 @@ export function startOfToday(): Date {
d.setHours(0, 0, 0, 0); d.setHours(0, 0, 0, 0);
return d; return d;
} }
export function parseLocalDate(dateStr: string): Date {
const [y, m, d] = dateStr.split("-").map(Number);
return new Date(y, m - 1, d);
}
export function startOfNextLocalDay(dateStr: string): Date {
const [y, m, d] = dateStr.split("-").map(Number);
return new Date(y, m - 1, d + 1);
}

View File

@@ -25,7 +25,9 @@ export const payExpenseSchema = z.object({
export const updateExpenseSchema = z.object({ export const updateExpenseSchema = z.object({
amount: z.number().positive("El monto debe ser mayor a 0"), amount: z.number().positive("El monto debe ser mayor a 0"),
dueDate: z.string().datetime({ message: "La fecha debe ser una fecha ISO válida" }), dueDate: z
.string()
.datetime({ message: "La fecha debe ser una fecha ISO válida" }),
}); });
function lastDayOfMonth(year: number, month: number): number { function lastDayOfMonth(year: number, month: number): number {

View File

@@ -2,6 +2,7 @@ import type { Context } from "hono";
import type { QuoteType } from "../../../generated/prisma/client"; import type { QuoteType } from "../../../generated/prisma/client";
import { cache } from "../../../lib/cache"; import { cache } from "../../../lib/cache";
import { prisma } from "../../../lib/prisma"; import { prisma } from "../../../lib/prisma";
import { parseLocalDate, startOfNextLocalDay } from "../../../lib/utils";
const VALID_TYPES = ["BLUE", "BNA", "BELO"] as const; const VALID_TYPES = ["BLUE", "BNA", "BELO"] as const;
@@ -22,11 +23,9 @@ export async function getDailyMinMax(c: Context) {
const now = new Date(); const now = new Date();
const startDate = startDateParam const startDate = startDateParam
? new Date(startDateParam) ? parseLocalDate(startDateParam)
: new Date(now.getFullYear(), now.getMonth(), 1); : new Date(now.getFullYear(), now.getMonth(), 1);
const endDate = endDateParam const endDate = endDateParam ? startOfNextLocalDay(endDateParam) : now;
? new Date(new Date(endDateParam).getTime() + 86_400_000)
: now;
if (Number.isNaN(startDate.getTime()) || Number.isNaN(endDate.getTime())) { if (Number.isNaN(startDate.getTime()) || Number.isNaN(endDate.getTime())) {
return c.json({ error: "Invalid date format. Use ISO 8601." }, 400); return c.json({ error: "Invalid date format. Use ISO 8601." }, 400);

View File

@@ -1,6 +1,7 @@
import type { Context } from "hono"; import type { Context } from "hono";
import { cache } from "../../../lib/cache"; import { cache } from "../../../lib/cache";
import { prisma } from "../../../lib/prisma"; import { prisma } from "../../../lib/prisma";
import { parseLocalDate, startOfNextLocalDay } from "../../../lib/utils";
const VALID_TYPES = ["BLUE", "BNA", "BELO"] as const; const VALID_TYPES = ["BLUE", "BNA", "BELO"] as const;
@@ -21,11 +22,9 @@ export async function getDailyQuotes(c: Context) {
const now = new Date(); const now = new Date();
const startDate = startDateParam const startDate = startDateParam
? new Date(startDateParam) ? parseLocalDate(startDateParam)
: new Date(now.getFullYear(), now.getMonth(), 1); : new Date(now.getFullYear(), now.getMonth(), 1);
const endDate = endDateParam const endDate = endDateParam ? startOfNextLocalDay(endDateParam) : now;
? new Date(new Date(endDateParam).getTime() + 86_400_000)
: now;
if (Number.isNaN(startDate.getTime()) || Number.isNaN(endDate.getTime())) { if (Number.isNaN(startDate.getTime()) || Number.isNaN(endDate.getTime())) {
return c.json({ error: "Invalid date format. Use ISO 8601." }, 400); return c.json({ error: "Invalid date format. Use ISO 8601." }, 400);

View File

@@ -2,6 +2,7 @@ import type { Context } from "hono";
import type { QuoteType } from "../../../generated/prisma/client"; import type { QuoteType } from "../../../generated/prisma/client";
import { cache } from "../../../lib/cache"; import { cache } from "../../../lib/cache";
import { prisma } from "../../../lib/prisma"; import { prisma } from "../../../lib/prisma";
import { parseLocalDate, startOfNextLocalDay } from "../../../lib/utils";
const VALID_TYPES = ["BLUE", "BNA", "BELO"] as const; const VALID_TYPES = ["BLUE", "BNA", "BELO"] as const;
@@ -23,11 +24,9 @@ export async function getQuoteHistory(c: Context) {
const now = new Date(); const now = new Date();
const startDate = startDateParam const startDate = startDateParam
? new Date(startDateParam) ? parseLocalDate(startDateParam)
: new Date(now.getFullYear(), now.getMonth(), 1); : new Date(now.getFullYear(), now.getMonth(), 1);
const endDate = endDateParam const endDate = endDateParam ? startOfNextLocalDay(endDateParam) : now;
? new Date(new Date(endDateParam).getTime() + 86_400_000)
: now;
if (Number.isNaN(startDate.getTime()) || Number.isNaN(endDate.getTime())) { if (Number.isNaN(startDate.getTime()) || Number.isNaN(endDate.getTime())) {
return c.json({ error: "Invalid date format. Use ISO 8601." }, 400); return c.json({ error: "Invalid date format. Use ISO 8601." }, 400);

View File

@@ -28,11 +28,8 @@ function formatDate(d: Date): string {
} }
function formatShortDate(iso: string): string { function formatShortDate(iso: string): string {
const d = new Date(iso); const [, m, d] = iso.split("-");
return d.toLocaleDateString("es-AR", { return `${d}/${m}`;
day: "2-digit",
month: "2-digit",
});
} }
export function BeloAnalysisPage() { export function BeloAnalysisPage() {
@@ -315,7 +312,7 @@ export function BeloAnalysisPage() {
}} }}
/> />
<Line <Line
type="monotone" type="linear"
dataKey="buy" dataKey="buy"
name="Compra" name="Compra"
stroke="var(--chart-1)" stroke="var(--chart-1)"

View File

@@ -46,11 +46,8 @@ function formatTime(iso: string): string {
} }
function formatShortDate(iso: string): string { function formatShortDate(iso: string): string {
const d = new Date(iso); const [, m, d] = iso.split("-");
return d.toLocaleDateString("es-AR", { return `${d}/${m}`;
day: "2-digit",
month: "2-digit",
});
} }
function getGaugeColor(percentage: number | null): string { function getGaugeColor(percentage: number | null): string {
@@ -395,7 +392,7 @@ export function BeloPage() {
}} }}
/> />
<Line <Line
type="monotone" type="linear"
dataKey="buy" dataKey="buy"
name="Compra" name="Compra"
stroke="var(--chart-1)" stroke="var(--chart-1)"
@@ -405,7 +402,7 @@ export function BeloPage() {
isAnimationActive={false} isAnimationActive={false}
/> />
<Line <Line
type="monotone" type="linear"
dataKey="sell" dataKey="sell"
name="Venta" name="Venta"
stroke="var(--chart-2)" stroke="var(--chart-2)"