mirror of
https://github.com/spliit-app/spliit.git
synced 2026-03-05 12:16:13 +01:00
Prevent date offset for expenses in local timezones (#433)
This commit is contained in:
@@ -5,7 +5,7 @@ import { DocumentsCount } from '@/app/groups/[groupId]/expenses/documents-count'
|
|||||||
import { Button } from '@/components/ui/button'
|
import { Button } from '@/components/ui/button'
|
||||||
import { getGroupExpenses } from '@/lib/api'
|
import { getGroupExpenses } from '@/lib/api'
|
||||||
import { Currency } from '@/lib/currency'
|
import { Currency } from '@/lib/currency'
|
||||||
import { cn, formatCurrency, formatDate } from '@/lib/utils'
|
import { cn, formatCurrency, formatDateOnly } from '@/lib/utils'
|
||||||
import { ChevronRight } from 'lucide-react'
|
import { ChevronRight } from 'lucide-react'
|
||||||
import { useLocale, useTranslations } from 'next-intl'
|
import { useLocale, useTranslations } from 'next-intl'
|
||||||
import Link from 'next/link'
|
import Link from 'next/link'
|
||||||
@@ -99,7 +99,7 @@ export function ExpenseCard({
|
|||||||
<DocumentsCount count={expense._count.documents} />
|
<DocumentsCount count={expense._count.documents} />
|
||||||
</div>
|
</div>
|
||||||
<div className="text-xs text-muted-foreground">
|
<div className="text-xs text-muted-foreground">
|
||||||
{formatDate(expense.expenseDate, locale, { dateStyle: 'medium' })}
|
{formatDateOnly(expense.expenseDate, locale, { dateStyle: 'medium' })}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<Button
|
<Button
|
||||||
|
|||||||
@@ -24,6 +24,34 @@ export function formatDate(
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Formats a date-only field (without time) for display.
|
||||||
|
* Extracts UTC date components to avoid timezone shifts that can cause off-by-one day errors.
|
||||||
|
* Use this for dates stored as DATE type in the database (e.g., expenseDate).
|
||||||
|
*
|
||||||
|
* @param date - The date to format (typically from a database DATE field, e.g., 2025-10-17T00:00:00.000Z)
|
||||||
|
* @param locale - The locale string (e.g., 'en-US', 'fr-FR')
|
||||||
|
* @param options - Formatting options (dateStyle, timeStyle)
|
||||||
|
* @returns Formatted date string in the specified locale
|
||||||
|
*/
|
||||||
|
export function formatDateOnly(
|
||||||
|
date: Date,
|
||||||
|
locale: string,
|
||||||
|
options: { dateStyle?: DateTimeStyle; timeStyle?: DateTimeStyle } = {},
|
||||||
|
) {
|
||||||
|
// Extract UTC date components to avoid timezone shifts
|
||||||
|
const year = date.getUTCFullYear()
|
||||||
|
const month = date.getUTCMonth()
|
||||||
|
const day = date.getUTCDate()
|
||||||
|
|
||||||
|
// Create a new date in the user's local timezone with these components
|
||||||
|
const localDate = new Date(year, month, day)
|
||||||
|
|
||||||
|
return localDate.toLocaleString(locale, {
|
||||||
|
...options,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
export function formatCategoryForAIPrompt(category: Category) {
|
export function formatCategoryForAIPrompt(category: Category) {
|
||||||
return `"${category.grouping}/${category.name}" (ID: ${category.id})`
|
return `"${category.grouping}/${category.name}" (ID: ${category.id})`
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user