diff --git a/web/src/lib/components/assets/thumbnail/thumbnail.svelte b/web/src/lib/components/assets/thumbnail/thumbnail.svelte index ec511d4192..8ee042a1a6 100644 --- a/web/src/lib/components/assets/thumbnail/thumbnail.svelte +++ b/web/src/lib/components/assets/thumbnail/thumbnail.svelte @@ -3,7 +3,7 @@ import Icon from '$lib/components/elements/icon.svelte'; import { ProjectionType } from '$lib/constants'; import { getAssetFileUrl, getAssetThumbnailUrl, isSharedLink } from '$lib/utils'; - import { timeToSeconds } from '$lib/utils/time-to-seconds'; + import { timeToSeconds } from '$lib/utils/date-time'; import { AssetTypeEnum, ThumbnailFormat, type AssetResponseDto } from '@immich/sdk'; import { mdiArchiveArrowDownOutline, diff --git a/web/src/lib/components/shared-components/search-bar/search-filter-box.svelte b/web/src/lib/components/shared-components/search-bar/search-filter-box.svelte index a19cf72a4c..1be3c95602 100644 --- a/web/src/lib/components/shared-components/search-bar/search-filter-box.svelte +++ b/web/src/lib/components/shared-components/search-bar/search-filter-box.svelte @@ -16,7 +16,7 @@ import { createEventDispatcher, onMount } from 'svelte'; import { fly } from 'svelte/transition'; import Combobox, { type ComboBoxOption } from '../combobox.svelte'; - import { DateTime } from 'luxon'; + import { parseUtcDate } from '$lib/utils/date-time'; enum MediaType { All = 'all', @@ -231,6 +231,9 @@ }; }; + const parseOptionalDate = (dateString?: string) => (dateString ? parseUtcDate(dateString) : undefined); + const toStartOfDayDate = (dateString: string) => parseUtcDate(dateString)?.startOf('day').toISODate() || undefined; + const search = async () => { let type: AssetTypeEnum | undefined = undefined; @@ -246,16 +249,11 @@ city: filter.location.city?.value, make: filter.camera.make?.value, model: filter.camera.model?.value, - takenAfter: filter.date.takenAfter - ? DateTime.fromFormat(filter.date.takenAfter, 'yyyy-MM-dd').toUTC().startOf('day').toString() - : undefined, - takenBefore: filter.date.takenBefore - ? DateTime.fromFormat(filter.date.takenBefore, 'yyyy-MM-dd').toUTC().endOf('day').toString() - : undefined, - /* eslint-disable unicorn/prefer-logical-operator-over-ternary */ - isArchived: filter.isArchive ? filter.isArchive : undefined, - isFavorite: filter.isFavorite ? filter.isFavorite : undefined, - isNotInAlbum: filter.isNotInAlbum ? filter.isNotInAlbum : undefined, + takenAfter: parseOptionalDate(filter.date.takenAfter)?.startOf('day').toISO() || undefined, + takenBefore: parseOptionalDate(filter.date.takenBefore)?.endOf('day').toISO() || undefined, + isArchived: filter.isArchive || undefined, + isFavorite: filter.isFavorite || undefined, + isNotInAlbum: filter.isNotInAlbum || undefined, personIds: filter.people && filter.people.length > 0 ? filter.people.map((p) => p.id) : undefined, type, }; @@ -295,12 +293,8 @@ model: searchQuery.model ? { label: searchQuery.model, value: searchQuery.model } : undefined, }, date: { - takenAfter: searchQuery.takenAfter - ? DateTime.fromISO(searchQuery.takenAfter).toUTC().toFormat('yyyy-MM-dd') - : undefined, - takenBefore: searchQuery.takenBefore - ? DateTime.fromISO(searchQuery.takenBefore).toUTC().toFormat('yyyy-MM-dd') - : undefined, + takenAfter: searchQuery.takenAfter ? toStartOfDayDate(searchQuery.takenAfter) : undefined, + takenBefore: searchQuery.takenBefore ? toStartOfDayDate(searchQuery.takenBefore) : undefined, }, isArchive: searchQuery.isArchived, isFavorite: searchQuery.isFavorite, diff --git a/web/src/lib/utils/time-to-seconds.spec.ts b/web/src/lib/utils/date-time.spec.ts similarity index 92% rename from web/src/lib/utils/time-to-seconds.spec.ts rename to web/src/lib/utils/date-time.spec.ts index 3e6cb0839a..cbb08418c0 100644 --- a/web/src/lib/utils/time-to-seconds.spec.ts +++ b/web/src/lib/utils/date-time.spec.ts @@ -1,4 +1,4 @@ -import { timeToSeconds } from './time-to-seconds'; +import { timeToSeconds } from './date-time'; describe('converting time to seconds', () => { it('parses hh:mm:ss correctly', () => { diff --git a/web/src/lib/utils/time-to-seconds.ts b/web/src/lib/utils/date-time.ts similarity index 68% rename from web/src/lib/utils/time-to-seconds.ts rename to web/src/lib/utils/date-time.ts index 026615ea03..f1eeee02bf 100644 --- a/web/src/lib/utils/time-to-seconds.ts +++ b/web/src/lib/utils/date-time.ts @@ -1,4 +1,4 @@ -import { Duration } from 'luxon'; +import { DateTime, Duration } from 'luxon'; /** * Convert time like `01:02:03.456` to seconds. @@ -11,3 +11,7 @@ export function timeToSeconds(time: string) { return Duration.fromObject({ hours, minutes, seconds }).as('seconds'); } + +export function parseUtcDate(date: string) { + return DateTime.fromISO(date, { zone: 'UTC' }).toUTC(); +} diff --git a/web/src/routes/(user)/search/+page.svelte b/web/src/routes/(user)/search/+page.svelte index fd84071d32..3d52ee04f2 100644 --- a/web/src/routes/(user)/search/+page.svelte +++ b/web/src/routes/(user)/search/+page.svelte @@ -35,6 +35,7 @@ import type { Viewport } from '$lib/stores/assets.store'; import { locale } from '$lib/stores/preferences.store'; import LoadingSpinner from '$lib/components/shared-components/loading-spinner.svelte'; + import { parseUtcDate } from '$lib/utils/date-time'; const MAX_ASSET_COUNT = 5000; let { isViewing: showAssetViewer } = assetViewingStore; @@ -143,13 +144,16 @@ isLoading = false; }; - function getHumanReadableDate(date: string) { - const d = new Date(date); - return d.toLocaleDateString($locale, { - year: 'numeric', - month: 'long', - day: 'numeric', - }); + function getHumanReadableDate(dateString: string) { + const date = parseUtcDate(dateString).startOf('day'); + return date.toLocaleString( + { + year: 'numeric', + month: 'long', + day: 'numeric', + }, + { locale: $locale }, + ); } function getHumanReadableSearchKey(key: keyof SearchTerms): string {