use Intl.DateTimeFormat and Intl.NumberFormat instead of toLocaleString (#9444)
This commit is contained in:
		
							parent
							
								
									0222165bd9
								
							
						
					
					
						commit
						c3a36698e5
					
				
					 14 changed files with 42 additions and 18 deletions
				
			
		|  | @ -10,7 +10,7 @@ | |||
| 		</MkA> | ||||
| 		<MkKeyValue class="_formBlock"> | ||||
| 			<template #key>{{ i18n.ts.registeredDate }}</template> | ||||
| 			<template #value>{{ new Date(report.targetUser.createdAt).toLocaleString() }} (<MkTime :time="report.targetUser.createdAt"/>)</template> | ||||
| 			<template #value>{{ dateString(report.targetUser.createdAt) }} (<MkTime :time="report.targetUser.createdAt"/>)</template> | ||||
| 		</MkKeyValue> | ||||
| 	</div> | ||||
| 	<div class="detail"> | ||||
|  | @ -42,6 +42,7 @@ import MkKeyValue from '@/components/MkKeyValue.vue'; | |||
| import { acct, userPage } from '@/filters/user'; | ||||
| import * as os from '@/os'; | ||||
| import { i18n } from '@/i18n'; | ||||
| import { dateString } from '@/filters/date'; | ||||
| 
 | ||||
| const props = defineProps<{ | ||||
| 	report: any; | ||||
|  |  | |||
|  | @ -40,6 +40,7 @@ import { defaultStore } from '@/store'; | |||
| import { useChartTooltip } from '@/scripts/use-chart-tooltip'; | ||||
| import { chartVLine } from '@/scripts/chart-vline'; | ||||
| import { alpha } from '@/scripts/color'; | ||||
| import date from '@/filters/date'; | ||||
| 
 | ||||
| const props = defineProps({ | ||||
| 	src: { | ||||
|  | @ -171,7 +172,7 @@ const render = () => { | |||
| 	chartInstance = new Chart(chartEl.value, { | ||||
| 		type: props.bar ? 'bar' : 'line', | ||||
| 		data: { | ||||
| 			labels: new Array(props.limit).fill(0).map((_, i) => getDate(i).toLocaleString()).slice().reverse(), | ||||
| 			labels: new Array(props.limit).fill(0).map((_, i) => date(getDate(i))).slice().reverse(), | ||||
| 			datasets: chartData.series.map((x, i) => ({ | ||||
| 				parsing: false, | ||||
| 				label: x.name, | ||||
|  |  | |||
|  | @ -4,7 +4,7 @@ | |||
| 		<MkA | ||||
| 			v-for="file in items" | ||||
| 			:key="file.id" | ||||
| 			v-tooltip.mfm="`${file.type}\n${bytes(file.size)}\n${new Date(file.createdAt).toLocaleString()}\nby ${file.user ? '@' + Acct.toString(file.user) : 'system'}`" | ||||
| 			v-tooltip.mfm="`${file.type}\n${bytes(file.size)}\n${dateString(file.createdAt)}\nby ${file.user ? '@' + Acct.toString(file.user) : 'system'}`" | ||||
| 			:to="`/admin/file/${file.id}`" | ||||
| 			class="file _button" | ||||
| 		> | ||||
|  | @ -39,6 +39,7 @@ import MkDriveFileThumbnail from '@/components/MkDriveFileThumbnail.vue'; | |||
| import bytes from '@/filters/bytes'; | ||||
| import * as os from '@/os'; | ||||
| import { i18n } from '@/i18n'; | ||||
| import { dateString } from '@/filters/date'; | ||||
| 
 | ||||
| const props = defineProps<{ | ||||
| 	pagination: any; | ||||
|  |  | |||
|  | @ -45,11 +45,12 @@ | |||
| 
 | ||||
| <script lang="ts" setup> | ||||
| import { defineAsyncComponent, onMounted, onUnmounted } from 'vue'; | ||||
| import { url as local, lang } from '@/config'; | ||||
| import { url as local } from '@/config'; | ||||
| import { i18n } from '@/i18n'; | ||||
| import * as os from '@/os'; | ||||
| import { deviceKind } from '@/scripts/device-kind'; | ||||
| import MkButton from '@/components/MkButton.vue'; | ||||
| import { versatileLang } from '@/scripts/intl-const'; | ||||
| 
 | ||||
| const props = withDefaults(defineProps<{ | ||||
| 	url: string; | ||||
|  | @ -95,11 +96,9 @@ if (requestUrl.hostname === 'music.youtube.com' && requestUrl.pathname.match('^/ | |||
| 	requestUrl.hostname = 'www.youtube.com'; | ||||
| } | ||||
| 
 | ||||
| const requestLang = (lang ?? 'ja-JP').replace('ja-KS', 'ja-JP'); | ||||
| 
 | ||||
| requestUrl.hash = ''; | ||||
| 
 | ||||
| window.fetch(`/url?url=${encodeURIComponent(requestUrl.href)}&lang=${requestLang}`).then(res => { | ||||
| window.fetch(`/url?url=${encodeURIComponent(requestUrl.href)}&lang=${versatileLang}`).then(res => { | ||||
| 	res.json().then(info => { | ||||
| 		if (info.url == null) { | ||||
| 			unknownUrl = true; | ||||
|  |  | |||
|  | @ -19,7 +19,7 @@ | |||
| 
 | ||||
| <script lang="ts" setup> | ||||
| import XWindow from '@/components/MkWindow.vue'; | ||||
| import { lang } from '@/config'; | ||||
| import { versatileLang } from '@/scripts/intl-const'; | ||||
| 
 | ||||
| const props = defineProps<{ | ||||
| 	url: string; | ||||
|  | @ -35,11 +35,9 @@ let player = $ref({ | |||
| 	height: null, | ||||
| }); | ||||
| 
 | ||||
| const requestLang = (lang ?? 'ja-JP').replace('ja-KS', 'ja-JP'); | ||||
| 
 | ||||
| const ytFetch = (): void => { | ||||
| 	fetching = true; | ||||
| 	window.fetch(`/url?url=${encodeURIComponent(requestUrl.href)}&lang=${requestLang}`).then(res => { | ||||
| 	window.fetch(`/url?url=${encodeURIComponent(requestUrl.href)}&lang=${versatileLang}`).then(res => { | ||||
| 		res.json().then(info => { | ||||
| 			if (info.url == null) return; | ||||
| 			title = info.title; | ||||
|  |  | |||
|  | @ -9,6 +9,7 @@ | |||
| <script lang="ts" setup> | ||||
| import { onUnmounted } from 'vue'; | ||||
| import { i18n } from '@/i18n'; | ||||
| import { dateTimeFormat } from '@/scripts/intl-const'; | ||||
| 
 | ||||
| const props = withDefaults(defineProps<{ | ||||
| 	time: Date | string; | ||||
|  | @ -18,7 +19,7 @@ const props = withDefaults(defineProps<{ | |||
| }); | ||||
| 
 | ||||
| const _time = typeof props.time === 'string' ? new Date(props.time) : props.time; | ||||
| const absolute = _time.toLocaleString(); | ||||
| const absolute = dateTimeFormat.format(_time); | ||||
| 
 | ||||
| let now = $shallowRef(new Date()); | ||||
| const relative = $computed(() => { | ||||
|  |  | |||
							
								
								
									
										4
									
								
								packages/frontend/src/filters/date.ts
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										4
									
								
								packages/frontend/src/filters/date.ts
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,4 @@ | |||
| import { dateTimeFormat } from '@/scripts/intl-const'; | ||||
| 
 | ||||
| export default (d: Date | number | undefined) => dateTimeFormat.format(d);  | ||||
| export const dateString = (d: string) => dateTimeFormat.format(new Date(d)); | ||||
|  | @ -1 +1,3 @@ | |||
| export default n => n == null ? 'N/A' : n.toLocaleString(); | ||||
| import { numberFormat } from '@/scripts/intl-const'; | ||||
| 
 | ||||
| export default n => n == null ? 'N/A' : numberFormat.format(n); | ||||
|  |  | |||
|  | @ -38,7 +38,7 @@ | |||
| 
 | ||||
| 	<MkPagination v-slot="{items}" ref="instances" :key="host + state" :pagination="pagination"> | ||||
| 		<div class="dqokceoi"> | ||||
| 			<MkA v-for="instance in items" :key="instance.id" v-tooltip.mfm="`Last communicated: ${new Date(instance.lastCommunicatedAt).toLocaleString()}\nStatus: ${getStatus(instance)}`" class="instance" :to="`/instance-info/${instance.host}`"> | ||||
| 			<MkA v-for="instance in items" :key="instance.id" v-tooltip.mfm="`Last communicated: ${dateString(instance.lastCommunicatedAt)}\nStatus: ${getStatus(instance)}`" class="instance" :to="`/instance-info/${instance.host}`"> | ||||
| 				<MkInstanceCardMini :instance="instance"/> | ||||
| 			</MkA> | ||||
| 		</div> | ||||
|  | @ -56,6 +56,7 @@ import MkInstanceCardMini from '@/components/MkInstanceCardMini.vue'; | |||
| import FormSplit from '@/components/form/split.vue'; | ||||
| import * as os from '@/os'; | ||||
| import { i18n } from '@/i18n'; | ||||
| import { dateString } from '@/filters/date'; | ||||
| 
 | ||||
| let host = $ref(''); | ||||
| let state = $ref('federating'); | ||||
|  |  | |||
|  | @ -41,7 +41,7 @@ | |||
| 					</div> | ||||
| 
 | ||||
| 					<MkPagination v-slot="{items}" ref="paginationComponent" :pagination="pagination" class="users"> | ||||
| 						<MkA v-for="user in items" :key="user.id" v-tooltip.mfm="`Last posted: ${new Date(user.updatedAt).toLocaleString()}`" class="user" :to="`/user-info/${user.id}`"> | ||||
| 						<MkA v-for="user in items" :key="user.id" v-tooltip.mfm="`Last posted: ${dateString(user.updatedAt)}`" class="user" :to="`/user-info/${user.id}`"> | ||||
| 							<MkUserCardMini :user="user"/> | ||||
| 						</MkA> | ||||
| 					</MkPagination> | ||||
|  | @ -63,6 +63,7 @@ import { lookupUser } from '@/scripts/lookup-user'; | |||
| import { i18n } from '@/i18n'; | ||||
| import { definePageMetadata } from '@/scripts/page-metadata'; | ||||
| import MkUserCardMini from '@/components/MkUserCardMini.vue'; | ||||
| import { dateString } from '@/filters/date'; | ||||
| 
 | ||||
| let paginationComponent = $ref<InstanceType<typeof MkPagination>>(); | ||||
| 
 | ||||
|  |  | |||
|  | @ -101,7 +101,7 @@ | |||
| 		</div> | ||||
| 		<div v-else-if="tab === 'users'" class="_formRoot"> | ||||
| 			<MkPagination v-slot="{items}" :pagination="usersPagination" style="display: grid; grid-template-columns: repeat(auto-fill,minmax(270px,1fr)); grid-gap: 12px;"> | ||||
| 				<MkA v-for="user in items" :key="user.id" v-tooltip.mfm="`Last posted: ${new Date(user.updatedAt).toLocaleString()}`" class="user" :to="`/user-info/${user.id}`"> | ||||
| 				<MkA v-for="user in items" :key="user.id" v-tooltip.mfm="`Last posted: ${dateString(user.updatedAt)}`" class="user" :to="`/user-info/${user.id}`"> | ||||
| 					<MkUserCardMini :user="user"/> | ||||
| 				</MkA> | ||||
| 			</MkPagination> | ||||
|  | @ -135,6 +135,7 @@ import { i18n } from '@/i18n'; | |||
| import MkUserCardMini from '@/components/MkUserCardMini.vue'; | ||||
| import MkPagination from '@/components/MkPagination.vue'; | ||||
| import { getProxiedImageUrlNullable } from '@/scripts/media-proxy'; | ||||
| import { dateString } from '@/filters/date'; | ||||
| 
 | ||||
| const props = defineProps<{ | ||||
| 	host: string; | ||||
|  |  | |||
|  | @ -51,6 +51,7 @@ import MkButton from '@/components/MkButton.vue'; | |||
| import * as os from '@/os'; | ||||
| import { definePageMetadata } from '@/scripts/page-metadata'; | ||||
| import { i18n } from '@/i18n'; | ||||
| import { dateString } from '@/filters/date'; | ||||
| 
 | ||||
| const props = defineProps<{ | ||||
| 	noteId: string; | ||||
|  | @ -127,7 +128,7 @@ const headerTabs = $computed(() => []); | |||
| 
 | ||||
| definePageMetadata(computed(() => note ? { | ||||
| 	title: i18n.ts.note, | ||||
| 	subtitle: new Date(note.createdAt).toLocaleString(), | ||||
| 	subtitle: dateString(note.createdAt), | ||||
| 	avatar: note.user, | ||||
| 	path: `/notes/${note.id}`, | ||||
| 	share: { | ||||
|  |  | |||
|  | @ -55,7 +55,7 @@ | |||
| 						</dl> | ||||
| 						<dl class="field"> | ||||
| 							<dt class="name"><i class="ti ti-calendar ti-fw"></i> {{ i18n.ts.registeredDate }}</dt> | ||||
| 							<dd class="value">{{ new Date(user.createdAt).toLocaleString() }} (<MkTime :time="user.createdAt"/>)</dd> | ||||
| 							<dd class="value">{{ dateString(user.createdAt) }} (<MkTime :time="user.createdAt"/>)</dd> | ||||
| 						</dl> | ||||
| 					</div> | ||||
| 					<div v-if="user.fields.length > 0" class="fields"> | ||||
|  | @ -127,6 +127,7 @@ import * as os from '@/os'; | |||
| import { useRouter } from '@/router'; | ||||
| import { i18n } from '@/i18n'; | ||||
| import { $i } from '@/account'; | ||||
| import { dateString } from '@/filters/date'; | ||||
| 
 | ||||
| const XPhotos = defineAsyncComponent(() => import('./index.photos.vue')); | ||||
| const XActivity = defineAsyncComponent(() => import('./index.activity.vue')); | ||||
|  |  | |||
							
								
								
									
										12
									
								
								packages/frontend/src/scripts/intl-const.ts
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										12
									
								
								packages/frontend/src/scripts/intl-const.ts
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,12 @@ | |||
| import { lang } from '@/config'; | ||||
| 
 | ||||
| export const versatileLang = (lang ?? 'ja-JP').replace('ja-KS', 'ja-JP'); | ||||
| export const dateTimeFormat = new Intl.DateTimeFormat(versatileLang, { | ||||
|     year: 'numeric', | ||||
|     month: 'numeric', | ||||
|     day: 'numeric', | ||||
|     hour: 'numeric', | ||||
|     minute: 'numeric', | ||||
|     second: 'numeric', | ||||
| }); | ||||
| export const numberFormat = new Intl.NumberFormat(versatileLang); | ||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue