Merge 65e137d276 into 07eea0f484
				
					
				
			This commit is contained in:
		
						commit
						a5691306c5
					
				
							
								
								
									
										9
									
								
								components.d.ts
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										9
									
								
								components.d.ts
									
									
									
									
										vendored
									
									
								
							| @ -130,19 +130,23 @@ declare module '@vue/runtime-core' { | ||||
|     MetaTagGenerator: typeof import('./src/tools/meta-tag-generator/meta-tag-generator.vue')['default'] | ||||
|     MimeTypes: typeof import('./src/tools/mime-types/mime-types.vue')['default'] | ||||
|     NavbarButtons: typeof import('./src/components/NavbarButtons.vue')['default'] | ||||
|     NCheckbox: typeof import('naive-ui')['NCheckbox'] | ||||
|     NCollapseTransition: typeof import('naive-ui')['NCollapseTransition'] | ||||
|     NConfigProvider: typeof import('naive-ui')['NConfigProvider'] | ||||
|     NDatePicker: typeof import('naive-ui')['NDatePicker'] | ||||
|     NDivider: typeof import('naive-ui')['NDivider'] | ||||
|     NDynamicInput: typeof import('naive-ui')['NDynamicInput'] | ||||
|     NEllipsis: typeof import('naive-ui')['NEllipsis'] | ||||
|     NFormItem: typeof import('naive-ui')['NFormItem'] | ||||
|     NH1: typeof import('naive-ui')['NH1'] | ||||
|     NH3: typeof import('naive-ui')['NH3'] | ||||
|     NIcon: typeof import('naive-ui')['NIcon'] | ||||
|     NInput: typeof import('naive-ui')['NInput'] | ||||
|     NLayout: typeof import('naive-ui')['NLayout'] | ||||
|     NLayoutSider: typeof import('naive-ui')['NLayoutSider'] | ||||
|     NMenu: typeof import('naive-ui')['NMenu'] | ||||
|     NSelect: typeof import('naive-ui')['NSelect'] | ||||
|     NSpace: typeof import('naive-ui')['NSpace'] | ||||
|     NTable: typeof import('naive-ui')['NTable'] | ||||
|     NSwitch: typeof import('naive-ui')['NSwitch'] | ||||
|     NumeronymGenerator: typeof import('./src/tools/numeronym-generator/numeronym-generator.vue')['default'] | ||||
|     OtpCodeGeneratorAndValidator: typeof import('./src/tools/otp-code-generator-and-validator/otp-code-generator-and-validator.vue')['default'] | ||||
|     PasswordStrengthAnalyser: typeof import('./src/tools/password-strength-analyser/password-strength-analyser.vue')['default'] | ||||
| @ -173,6 +177,7 @@ declare module '@vue/runtime-core' { | ||||
|     TextToBinary: typeof import('./src/tools/text-to-binary/text-to-binary.vue')['default'] | ||||
|     TextToNatoAlphabet: typeof import('./src/tools/text-to-nato-alphabet/text-to-nato-alphabet.vue')['default'] | ||||
|     TextToUnicode: typeof import('./src/tools/text-to-unicode/text-to-unicode.vue')['default'] | ||||
|     TimezoneConverter: typeof import('./src/tools/timezone-converter/timezone-converter.vue')['default'] | ||||
|     TokenDisplay: typeof import('./src/tools/otp-code-generator-and-validator/token-display.vue')['default'] | ||||
|     'TokenGenerator.tool': typeof import('./src/tools/token-generator/token-generator.tool.vue')['default'] | ||||
|     TomlToJson: typeof import('./src/tools/toml-to-json/toml-to-json.vue')['default'] | ||||
|  | ||||
| @ -56,6 +56,7 @@ | ||||
|     "change-case": "^4.1.2", | ||||
|     "colord": "^2.9.3", | ||||
|     "composerize-ts": "^0.6.2", | ||||
|     "countries-and-timezones": "^3.6.0", | ||||
|     "country-code-lookup": "^0.1.0", | ||||
|     "cron-validator": "^1.3.1", | ||||
|     "cronstrue": "^2.26.0", | ||||
| @ -67,6 +68,7 @@ | ||||
|     "figlet": "^1.7.0", | ||||
|     "figue": "^1.2.0", | ||||
|     "fuse.js": "^6.6.2", | ||||
|     "get-timezone-offset": "^1.0.5", | ||||
|     "highlight.js": "^11.7.0", | ||||
|     "iarna-toml-esm": "^3.0.5", | ||||
|     "ibantools": "^4.3.3", | ||||
|  | ||||
							
								
								
									
										14462
									
								
								pnpm-lock.yaml
									
									
									
										generated
									
									
									
								
							
							
						
						
									
										14462
									
								
								pnpm-lock.yaml
									
									
									
										generated
									
									
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							| @ -9,6 +9,7 @@ import { tool as textToUnicode } from './text-to-unicode'; | ||||
| import { tool as safelinkDecoder } from './safelink-decoder'; | ||||
| import { tool as xmlToJson } from './xml-to-json'; | ||||
| import { tool as jsonToXml } from './json-to-xml'; | ||||
| import { tool as timezoneConverter } from './timezone-converter'; | ||||
| import { tool as regexTester } from './regex-tester'; | ||||
| import { tool as regexMemo } from './regex-memo'; | ||||
| import { tool as markdownToHtml } from './markdown-to-html'; | ||||
| @ -97,6 +98,7 @@ export const toolsByCategory: ToolCategory[] = [ | ||||
|     name: 'Converter', | ||||
|     components: [ | ||||
|       dateTimeConverter, | ||||
|       timezoneConverter, | ||||
|       baseConverter, | ||||
|       romanNumeralConverter, | ||||
|       base64StringConverter, | ||||
|  | ||||
							
								
								
									
										3
									
								
								src/tools/timezone-converter/get-timezone-offset.d.ts
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										3
									
								
								src/tools/timezone-converter/get-timezone-offset.d.ts
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @ -0,0 +1,3 @@ | ||||
| declare module "get-timezone-offset" { | ||||
|     export default function(timeZoneName: string, date: Date); | ||||
| } | ||||
							
								
								
									
										12
									
								
								src/tools/timezone-converter/index.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										12
									
								
								src/tools/timezone-converter/index.ts
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,12 @@ | ||||
| import { CalendarTime } from '@vicons/tabler'; | ||||
| import { defineTool } from '../tool'; | ||||
| 
 | ||||
| export const tool = defineTool({ | ||||
|   name: 'Timezone Converter', | ||||
|   path: '/timezone-converter', | ||||
|   description: 'Convert Date-Time from a timezone to others and get timezone vs countries infos', | ||||
|   keywords: ['timezone', 'tz', 'date', 'time', 'country', 'converter'], | ||||
|   component: () => import('./timezone-converter.vue'), | ||||
|   icon: CalendarTime, | ||||
|   createdAt: new Date('2024-08-15'), | ||||
| }); | ||||
							
								
								
									
										141
									
								
								src/tools/timezone-converter/timezone-converter.vue
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										141
									
								
								src/tools/timezone-converter/timezone-converter.vue
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,141 @@ | ||||
| <script setup lang="ts"> | ||||
| import ctz from 'countries-and-timezones'; | ||||
| import getTimezoneOffset from 'get-timezone-offset'; | ||||
| 
 | ||||
| const browserTimezone = Intl.DateTimeFormat().resolvedOptions().timeZone; | ||||
| const allTimezones = Object.values(ctz.getAllTimezones()).map(tz => ({ | ||||
|   value: tz.name, | ||||
|   label: `${tz.name === browserTimezone ? 'Browser TZ - ' : ''}${tz.name} (${tz.utcOffset === tz.dstOffset ? tz.utcOffsetStr : `${tz.utcOffsetStr}/${tz.dstOffsetStr}`})`, | ||||
| })); | ||||
| 
 | ||||
| function convertMinsToHrsMins(minutes: number) { | ||||
|   const h = String(Math.floor(minutes / 60)).padStart(2, '0'); | ||||
|   const m = String(minutes % 60).padStart(2, '0'); | ||||
|   return `${h}:${m}`; | ||||
| } | ||||
| 
 | ||||
| const otherTimezones = useStorage<{ name: string }[]>('timezone-conv:zones', [{ name: 'Etc/GMT' }]); | ||||
| const currentTimezone = useStorage<string>('timezone-conv:current', browserTimezone); | ||||
| const use24HourTimeFormat = useStorage<boolean>('timezone-conv:24h', true); | ||||
| const format = computed(() => use24HourTimeFormat.value ? 'yyyy-MM-dd HH:mm:ss' : 'yyyy-MM-dd hh:mm:ss a'); | ||||
| const timePickerProps = computed(() => use24HourTimeFormat.value ? ({ use12Hours: false }) : ({ use12Hours: true })); | ||||
| 
 | ||||
| const now = Date.now(); | ||||
| const currentDatetimeRange = ref<[number, number]>([now, now]); | ||||
| const currentTimezoneOffset = computed(() => { | ||||
|   return convertMinsToHrsMins(-getTimezoneOffset(currentTimezone.value, new Date(currentDatetimeRange.value[0]))); | ||||
| }); | ||||
| function convertToTimezone(tz: string, timestamp: number) { | ||||
|   return new Date( | ||||
|     timestamp | ||||
|     + getTimezoneOffset(currentTimezone.value, new Date()) * 60 * 1000 | ||||
|     - getTimezoneOffset(browserTimezone, new Date()) * 60 * 1000, | ||||
|   ).toLocaleString(undefined, | ||||
|     { timeZone: tz, timeZoneName: undefined, hour12: !use24HourTimeFormat.value }); | ||||
| } | ||||
| 
 | ||||
| const tzToCountriesInput = ref(browserTimezone); | ||||
| const tzToCountriesOutput = computed(() => ctz.getCountriesForTimezone(tzToCountriesInput.value)); | ||||
| 
 | ||||
| const allCountries = Object.values(ctz.getAllCountries()).map(c => ({ | ||||
|   value: c.id, | ||||
|   label: `${c.name} (${c.id})`, | ||||
| })); | ||||
| const countryToTimezonesInput = ref('FR'); | ||||
| const countryToTimezonesOutput = computed(() => ctz.getTimezonesForCountry(countryToTimezonesInput.value)); | ||||
| </script> | ||||
| 
 | ||||
| <template> | ||||
|   <div> | ||||
|     <c-card title="Timezones Date-Time Converter" mb-2> | ||||
|       <c-select | ||||
|         v-model:value="currentTimezone" | ||||
|         label="Timezone" | ||||
|         label-position="left" | ||||
|         searchable | ||||
|         :options="allTimezones" | ||||
|         mb-2 | ||||
|       /> | ||||
|       <n-form-item label="Date/time interval to convert:" label-placement="top"> | ||||
|         <n-date-picker | ||||
|           :key="format" | ||||
|           v-model:value="currentDatetimeRange" | ||||
|           type="datetimerange" | ||||
|           :format="format" | ||||
|           :time-picker-props="timePickerProps" | ||||
|           mb-2 | ||||
|           w-full | ||||
|         /> | ||||
|       </n-form-item> | ||||
| 
 | ||||
|       <n-space justify="space-evenly"> | ||||
|         <n-form-item label="Current Timezone Offset:" label-placement="left"> | ||||
|           <n-input :value="currentTimezoneOffset" readonly style="width:5em" /> | ||||
|         </n-form-item> | ||||
|         <n-form-item label="Use 24 hour time format" label-placement="left"> | ||||
|           <n-switch v-model:value="use24HourTimeFormat" /> | ||||
|         </n-form-item> | ||||
|       </n-space> | ||||
| 
 | ||||
|       <c-card title="Date-Time in other timezones"> | ||||
|         <n-dynamic-input | ||||
|           v-model:value="otherTimezones" | ||||
|           show-sort-button | ||||
|           :on-create="() => ({ name: browserTimezone })" | ||||
|         > | ||||
|           <template #default="{ value }"> | ||||
|             <div flex flex-wrap items-center gap-1> | ||||
|               <n-select | ||||
|                 v-model:value="value.name" | ||||
|                 filterable | ||||
|                 placeholder="Please select a timezone" | ||||
|                 :options="allTimezones" | ||||
|                 w-full | ||||
|               /> | ||||
|               <div w-full flex items-baseline gap-1> | ||||
|                 <n-input style="min-width: 49%" readonly :value="convertToTimezone(value.name, currentDatetimeRange[0])" /> | ||||
|                 <n-input style="min-width: 49%" readonly :value="convertToTimezone(value.name, currentDatetimeRange[1])" /> | ||||
|               </div> | ||||
|             </div> | ||||
|           </template> | ||||
|         </n-dynamic-input> | ||||
|       </c-card> | ||||
|     </c-card> | ||||
| 
 | ||||
|     <c-card title="Country to Timezones" mb-2> | ||||
|       <c-select | ||||
|         v-model:value="countryToTimezonesInput" | ||||
|         label="Country" | ||||
|         label-position="left" | ||||
|         searchable | ||||
|         :options="allCountries" | ||||
|       /> | ||||
| 
 | ||||
|       <n-divider /> | ||||
| 
 | ||||
|       <ul> | ||||
|         <li v-for="(tz, ix) in countryToTimezonesOutput" :key="ix"> | ||||
|           {{ tz.name }} ({{ tz.countries.join(', ') }}): UTC= {{ tz.utcOffsetStr }}, DST= {{ tz.dstOffsetStr }} | ||||
|         </li> | ||||
|       </ul> | ||||
|     </c-card> | ||||
| 
 | ||||
|     <c-card title="Timezones to Countries" mb-2> | ||||
|       <c-select | ||||
|         v-model:value="tzToCountriesInput" | ||||
|         label="Timezone" | ||||
|         label-position="left" | ||||
|         searchable | ||||
|         :options="allTimezones" | ||||
|       /> | ||||
| 
 | ||||
|       <n-divider /> | ||||
| 
 | ||||
|       <ul> | ||||
|         <li v-for="(country, ix) in tzToCountriesOutput" :key="ix"> | ||||
|           {{ country.name }} ({{ country.id }}): {{ country.timezones.join(', ') }} | ||||
|         </li> | ||||
|       </ul> | ||||
|     </c-card> | ||||
|   </div> | ||||
| </template> | ||||
		Loading…
	
		Reference in New Issue
	
	Block a user