diff --git a/src/features/dashboard/billing/concurrent-sandboxes-addon-dialog.tsx b/src/features/dashboard/billing/concurrent-sandboxes-addon-dialog.tsx
index a2f2a16be..cb4e0459b 100644
--- a/src/features/dashboard/billing/concurrent-sandboxes-addon-dialog.tsx
+++ b/src/features/dashboard/billing/concurrent-sandboxes-addon-dialog.tsx
@@ -142,11 +142,11 @@ function DialogContent_Inner({
const limitIncreaseText = currentConcurrentSandboxesLimit ? (
<>
Increases total concurrent sandbox limit from{' '}
- {currentConcurrentSandboxesLimit.toLocaleString()} to{' '}
+ {currentConcurrentSandboxesLimit.toLocaleString('en-US')} to{' '}
- {(
- currentConcurrentSandboxesLimit + SANDBOXES_PER_ADDON
- ).toLocaleString()}
+ {(currentConcurrentSandboxesLimit + SANDBOXES_PER_ADDON).toLocaleString(
+ 'en-US'
+ )}
>
) : (
diff --git a/src/features/dashboard/sandbox/events/table.tsx b/src/features/dashboard/sandbox/events/table.tsx
index 9bacac74a..cf52711d4 100644
--- a/src/features/dashboard/sandbox/events/table.tsx
+++ b/src/features/dashboard/sandbox/events/table.tsx
@@ -53,7 +53,7 @@ export const SandboxEventsTable = ({
}
- const date = new Date(endedAt)
- const now = new Date()
- const isToday = date.toDateString() === now.toDateString()
- const isYesterday =
- date.toDateString() ===
- new Date(now.setDate(now.getDate() - 1)).toDateString()
-
- const prefix = isToday
- ? 'Today'
- : isYesterday
- ? 'Yesterday'
- : date.toLocaleDateString()
-
- const timeStr = date.toLocaleTimeString([], {
- hour: 'numeric',
- minute: '2-digit',
- second: '2-digit',
- })
-
return (
-
- {prefix}, {timeStr}
-
-
+
+
)
}
diff --git a/src/features/dashboard/sandbox/inspect/stopped-banner.tsx b/src/features/dashboard/sandbox/inspect/stopped-banner.tsx
index c9b1c9683..903a508f5 100644
--- a/src/features/dashboard/sandbox/inspect/stopped-banner.tsx
+++ b/src/features/dashboard/sandbox/inspect/stopped-banner.tsx
@@ -64,7 +64,7 @@ export function StoppedBanner({ rootNodeCount }: StoppedBannerProps) {
: 'Filesystem data is stale and is kept locally on your device.'}
{' '}
- Last updated: {lastUpdated?.toLocaleTimeString()}
+ Last updated: {lastUpdated?.toLocaleTimeString('en-US')}
diff --git a/src/features/dashboard/sandbox/logs/logs-cells.tsx b/src/features/dashboard/sandbox/logs/logs-cells.tsx
index 15c138a55..26788fbfe 100644
--- a/src/features/dashboard/sandbox/logs/logs-cells.tsx
+++ b/src/features/dashboard/sandbox/logs/logs-cells.tsx
@@ -1,19 +1,8 @@
import type { SandboxLogModel } from '@/core/modules/sandboxes/models'
import { LogLevelBadge } from '@/features/dashboard/common/log-cells'
+import { formatLocalLogStyleTimestamp } from '@/lib/utils/formatting'
import CopyButtonInline from '@/ui/copy-button-inline'
-const LOCAL_DATE_FORMATTER = new Intl.DateTimeFormat(undefined, {
- month: 'short',
- day: '2-digit',
-})
-
-const LOCAL_TIME_FORMATTER = new Intl.DateTimeFormat(undefined, {
- hour: '2-digit',
- minute: '2-digit',
- second: '2-digit',
- hour12: false,
-})
-
export const LogLevel = ({ level }: { level: SandboxLogModel['level'] }) => {
return
}
@@ -23,21 +12,21 @@ interface TimestampProps {
}
export const Timestamp = ({ timestampUnix }: TimestampProps) => {
- const date = new Date(timestampUnix)
+ const formatted = formatLocalLogStyleTimestamp(timestampUnix, {
+ includeCentiseconds: true,
+ })
- const centiseconds = Math.floor((date.getMilliseconds() / 10) % 100)
- .toString()
- .padStart(2, '0')
- const localDatePart = LOCAL_DATE_FORMATTER.format(date)
- const localTimePart = LOCAL_TIME_FORMATTER.format(date)
+ if (!formatted) {
+ return --
+ }
return (
- {localDatePart} {localTimePart}.
- {centiseconds}
+ {formatted.datePart}{' '}
+ {formatted.timePart}.{formatted.subsecondPart}
)
}
diff --git a/src/features/dashboard/sandbox/logs/logs.tsx b/src/features/dashboard/sandbox/logs/logs.tsx
index 1ecdecc1a..c418f637c 100644
--- a/src/features/dashboard/sandbox/logs/logs.tsx
+++ b/src/features/dashboard/sandbox/logs/logs.tsx
@@ -39,7 +39,7 @@ import useLogFilters from './use-log-filters'
import { useSandboxLogs } from './use-sandbox-logs'
// column widths are calculated as max width of the content + padding
-const COLUMN_WIDTHS_PX = { timestamp: 148 + 16, level: 48 + 16 } as const
+const COLUMN_WIDTHS_PX = { timestamp: 190, level: 48 + 16 } as const
const ROW_HEIGHT_PX = 26
const LIVE_STATUS_ROW_HEIGHT_PX = ROW_HEIGHT_PX + 16
const VIRTUAL_OVERSCAN = 16
diff --git a/src/features/dashboard/sandbox/monitoring/components/monitoring-charts.tsx b/src/features/dashboard/sandbox/monitoring/components/monitoring-charts.tsx
index 87062f40a..83fd304e7 100644
--- a/src/features/dashboard/sandbox/monitoring/components/monitoring-charts.tsx
+++ b/src/features/dashboard/sandbox/monitoring/components/monitoring-charts.tsx
@@ -174,7 +174,9 @@ function renderUsageMarker(usedMb: number | null, value: number) {
return (
<>
- {normalizedUsedMb.toLocaleString()}
+
+ {normalizedUsedMb.toLocaleString('en-US')}
+
MB
ยท
{Math.round(value)}
diff --git a/src/features/dashboard/sandboxes/list/table-cells.tsx b/src/features/dashboard/sandboxes/list/table-cells.tsx
index 8cc5e4983..615206969 100644
--- a/src/features/dashboard/sandboxes/list/table-cells.tsx
+++ b/src/features/dashboard/sandboxes/list/table-cells.tsx
@@ -170,7 +170,7 @@ export function StartedAtCell({
const dateValue = (getValue() as string | undefined) ?? ''
const formattedTimestamp = useMemo(() => {
- return formatLocalLogStyleTimestamp(dateValue)
+ return formatLocalLogStyleTimestamp(dateValue, { includeTimezone: true })
}, [dateValue])
return (
diff --git a/src/features/dashboard/templates/list/table-cells.tsx b/src/features/dashboard/templates/list/table-cells.tsx
index 767a947e0..f550c811b 100644
--- a/src/features/dashboard/templates/list/table-cells.tsx
+++ b/src/features/dashboard/templates/list/table-cells.tsx
@@ -322,6 +322,7 @@ export function CreatedAtCell({
return formatLocalLogStyleTimestamp(dateValue, {
includeSeconds: false,
includeYear: true,
+ includeTimezone: true,
})
}, [dateValue])
@@ -351,6 +352,7 @@ export function UpdatedAtCell({
return formatLocalLogStyleTimestamp(dateValue, {
includeSeconds: false,
includeYear: true,
+ includeTimezone: true,
})
}, [dateValue])
diff --git a/src/lib/utils/formatting.ts b/src/lib/utils/formatting.ts
index cfe2f4fc9..529152c4c 100644
--- a/src/lib/utils/formatting.ts
+++ b/src/lib/utils/formatting.ts
@@ -7,13 +7,13 @@ import * as chrono from 'chrono-node'
import { format, isThisYear, isValid } from 'date-fns'
import { formatInTimeZone } from 'date-fns-tz'
-const LOCAL_LOG_STYLE_DATE_FORMATTER = new Intl.DateTimeFormat(undefined, {
+const LOCAL_LOG_STYLE_DATE_FORMATTER = new Intl.DateTimeFormat('en-US', {
month: 'short',
day: '2-digit',
})
const LOCAL_LOG_STYLE_DATE_WITH_YEAR_FORMATTER = new Intl.DateTimeFormat(
- undefined,
+ 'en-US',
{
month: 'short',
day: '2-digit',
@@ -21,7 +21,7 @@ const LOCAL_LOG_STYLE_DATE_WITH_YEAR_FORMATTER = new Intl.DateTimeFormat(
}
)
-const LOCAL_LOG_STYLE_TIME_FORMATTER = new Intl.DateTimeFormat(undefined, {
+const LOCAL_LOG_STYLE_TIME_FORMATTER = new Intl.DateTimeFormat('en-US', {
hour: '2-digit',
minute: '2-digit',
second: '2-digit',
@@ -29,7 +29,7 @@ const LOCAL_LOG_STYLE_TIME_FORMATTER = new Intl.DateTimeFormat(undefined, {
})
const LOCAL_LOG_STYLE_TIME_NO_SECONDS_FORMATTER = new Intl.DateTimeFormat(
- undefined,
+ 'en-US',
{
hour: '2-digit',
minute: '2-digit',
@@ -37,7 +37,7 @@ const LOCAL_LOG_STYLE_TIME_NO_SECONDS_FORMATTER = new Intl.DateTimeFormat(
}
)
-const LOCAL_LOG_STYLE_TIMEZONE_FORMATTER = new Intl.DateTimeFormat(undefined, {
+const LOCAL_LOG_STYLE_TIMEZONE_FORMATTER = new Intl.DateTimeFormat('en-US', {
timeZoneName: 'short',
})
@@ -55,16 +55,18 @@ export function formatLocalLogStyleTimestamp(
includeSeconds = true,
includeYear = false,
includeCentiseconds = false,
+ includeTimezone = false,
}: {
includeSeconds?: boolean
includeYear?: boolean
includeCentiseconds?: boolean
+ includeTimezone?: boolean
} = {}
): {
datePart: string
timePart: string
subsecondPart: string | null
- timezonePart: string
+ timezonePart: string | null
iso: string
} | null {
const date = new Date(timestamp)
@@ -73,12 +75,13 @@ export function formatLocalLogStyleTimestamp(
return null
}
- const timezonePart =
- LOCAL_LOG_STYLE_TIMEZONE_FORMATTER.formatToParts(date).find(
- (part) => part.type === 'timeZoneName'
- )?.value ??
- Intl.DateTimeFormat().resolvedOptions().timeZone ??
- 'Local'
+ const timezonePart = includeTimezone
+ ? (LOCAL_LOG_STYLE_TIMEZONE_FORMATTER.formatToParts(date).find(
+ (part) => part.type === 'timeZoneName'
+ )?.value ??
+ Intl.DateTimeFormat().resolvedOptions().timeZone ??
+ 'Local')
+ : null
return {
datePart: (includeYear
@@ -148,8 +151,8 @@ export const formatDisplayTimestamp = (value: string | number | Date) => {
? 'Today'
: isYesterday
? 'Yesterday'
- : date.toLocaleDateString()
- const timeStr = date.toLocaleTimeString([], {
+ : date.toLocaleDateString('en-US')
+ const timeStr = date.toLocaleTimeString('en-US', {
hour: 'numeric',
minute: '2-digit',
second: '2-digit',
diff --git a/src/ui/primitives/calendar.tsx b/src/ui/primitives/calendar.tsx
index b2c430fc1..ca8fd57fc 100644
--- a/src/ui/primitives/calendar.tsx
+++ b/src/ui/primitives/calendar.tsx
@@ -108,10 +108,10 @@ function Calendar({
disabled={disabledDates}
formatters={{
formatMonthDropdown: (date) =>
- date.toLocaleString('default', { month: 'short' }),
+ date.toLocaleString('en-US', { month: 'short' }),
formatWeekdayName: (date) =>
date
- .toLocaleString('default', { weekday: 'short' })
+ .toLocaleString('en-US', { weekday: 'short' })
.toUpperCase()
.slice(0, 3),
...formatters,
@@ -255,7 +255,7 @@ function CalendarDayButton({
ref={ref}
variant="tertiary"
size="none"
- data-day={day.date.toLocaleDateString()}
+ data-day={day.date.toLocaleDateString('en-US')}
data-selected-single={
modifiers.selected &&
!modifiers.range_start &&
diff --git a/src/ui/primitives/chart.tsx b/src/ui/primitives/chart.tsx
index db761329f..11d9c5075 100644
--- a/src/ui/primitives/chart.tsx
+++ b/src/ui/primitives/chart.tsx
@@ -276,14 +276,14 @@ const ChartTooltipContent = React.forwardRef<
{itemConfig?.label || item.name}
- {item.value && (
+ {item.value != null && (
- {item.value.toLocaleString()}
+ {item.value.toLocaleString('en-US')}
)}
diff --git a/src/ui/time-range-picker.logic.ts b/src/ui/time-range-picker.logic.ts
index 36f571791..585950bf8 100644
--- a/src/ui/time-range-picker.logic.ts
+++ b/src/ui/time-range-picker.logic.ts
@@ -193,18 +193,17 @@ export function parsePickerDateTime(
}
function formatBoundaryDateTime(date: Date, hideTime: boolean): string {
+ const datePart = formatDateValue(date)
if (hideTime) {
- return date.toLocaleDateString()
+ return datePart
}
- return date.toLocaleString(undefined, {
- year: 'numeric',
- month: 'numeric',
- day: 'numeric',
- hour: '2-digit',
- minute: '2-digit',
- second: '2-digit',
- })
+ const timePart = formatTimeValue(
+ date.getHours(),
+ date.getMinutes(),
+ date.getSeconds()
+ )
+ return `${datePart} ${timePart}`
}
function normalizeTimeValue(time: string | null): string | null {