Added more test cases including github server, updated functions in epoch-converter.service.ts
This commit is contained in:
		
							parent
							
								
									00b1148e3a
								
							
						
					
					
						commit
						965e6ccd50
					
				| @ -13,7 +13,8 @@ test.describe('Tool - Epoch converter', () => { | |||||||
|     await page.getByPlaceholder('Enter epoch timestamp').fill('1750452480'); |     await page.getByPlaceholder('Enter epoch timestamp').fill('1750452480'); | ||||||
|     await page.getByRole('button', { name: 'Convert to Date' }).click(); |     await page.getByRole('button', { name: 'Convert to Date' }).click(); | ||||||
| 
 | 
 | ||||||
|     await expect(page.getByText('6/23/2025, 12:31:00 PM')).toBeVisible(); |     await expect(page.getByText('GMT (UTC): Fri, 20 Jun 2025 20:48:00 GMT')).toBeVisible(); | ||||||
|  |     await expect(page.getByText('Local Time: Fri, 20 Jun 2025, 13:48:00 GMT-7')).toBeVisible(); | ||||||
|   }); |   }); | ||||||
| 
 | 
 | ||||||
|   test('Converts known date to epoch timestamp', async ({ page }) => { |   test('Converts known date to epoch timestamp', async ({ page }) => { | ||||||
| @ -28,4 +29,40 @@ test.describe('Tool - Epoch converter', () => { | |||||||
| 
 | 
 | ||||||
|     await expect(page.getByText('1750452480')).toBeVisible(); |     await expect(page.getByText('1750452480')).toBeVisible(); | ||||||
|   }); |   }); | ||||||
|  | 
 | ||||||
|  |   test('Shows error if year is not 4 digits', async ({ page }) => { | ||||||
|  |     await page.getByPlaceholder('YYYY').fill('99'); | ||||||
|  |     await page.getByRole('button', { name: 'Convert to Epoch (Local)' }).click(); | ||||||
|  |     await expect(page.getByText('Year must be 4 digits')).toBeVisible(); | ||||||
|  |   }); | ||||||
|  | 
 | ||||||
|  |   test('Shows error if month is invalid', async ({ page }) => { | ||||||
|  |     await page.getByPlaceholder('MM').first().fill('00'); | ||||||
|  |     await page.getByRole('button', { name: 'Convert to Epoch (Local)' }).click(); | ||||||
|  |     await expect(page.getByText('Month must be between 1 and 12')).toBeVisible(); | ||||||
|  |   }); | ||||||
|  | 
 | ||||||
|  |   test('Shows error if day is invalid', async ({ page }) => { | ||||||
|  |     await page.getByPlaceholder('DD').fill('0'); | ||||||
|  |     await page.getByRole('button', { name: 'Convert to Epoch (UTC)' }).click(); | ||||||
|  |     await expect(page.getByText('Day must be between 1 and 31')).toBeVisible(); | ||||||
|  |   }); | ||||||
|  | 
 | ||||||
|  |   test('Shows error if hour is invalid', async ({ page }) => { | ||||||
|  |     await page.getByPlaceholder('HH').fill('24'); | ||||||
|  |     await page.getByRole('button', { name: 'Convert to Epoch (Local)' }).click(); | ||||||
|  |     await expect(page.getByText('Hour must be between 0 and 23')).toBeVisible(); | ||||||
|  |   }); | ||||||
|  | 
 | ||||||
|  |   test('Shows error if minute is invalid', async ({ page }) => { | ||||||
|  |     await page.getByPlaceholder('MM').nth(1).fill('61'); | ||||||
|  |     await page.getByRole('button', { name: 'Convert to Epoch (UTC)' }).click(); | ||||||
|  |     await expect(page.getByText('Minute must be between 0 and 59')).toBeVisible(); | ||||||
|  |   }); | ||||||
|  | 
 | ||||||
|  |   test('Shows error if second is invalid', async ({ page }) => { | ||||||
|  |     await page.getByPlaceholder('SS').fill('99'); | ||||||
|  |     await page.getByRole('button', { name: 'Convert to Epoch (UTC)' }).click(); | ||||||
|  |     await expect(page.getByText('Second must be between 0 and 59')).toBeVisible(); | ||||||
|  |   }); | ||||||
| }); | }); | ||||||
|  | |||||||
| @ -1,12 +1,22 @@ | |||||||
|  | import process from 'node:process'; | ||||||
| import { describe, expect, it } from 'vitest'; | import { describe, expect, it } from 'vitest'; | ||||||
| import { dateToEpoch, epochToDate } from './epoch-converter.service'; | import { type DateParts, dateToEpoch, epochToDate, getISODateString } from './epoch-converter.service'; | ||||||
|  | 
 | ||||||
|  | process.env.TZ = 'America/Vancouver'; | ||||||
| 
 | 
 | ||||||
| describe('epochToDate', () => { | describe('epochToDate', () => { | ||||||
|   it('converts known epoch seconds to correct local date string', () => { |   it('converts known epoch seconds to correct formatted date (America/Vancouver)', () => { | ||||||
|     const epoch = 1750707060; |     const epoch = 1750707060; | ||||||
|     const expectedDate = '6/23/2025, 12:31:00 PM'; |     const expectedUTC = 'Mon, 23 Jun 2025 19:31:00 GMT'; | ||||||
|     const result = epochToDate(epoch); |     const expectedLocal = 'Mon, Jun 23, 2025, 12:31:00 PDT'; | ||||||
|     expect(result).toBe(expectedDate); | 
 | ||||||
|  |     const result = epochToDate(epoch, { | ||||||
|  |       timeZone: 'America/Vancouver', | ||||||
|  |       locale: 'en-US', | ||||||
|  |     }); | ||||||
|  | 
 | ||||||
|  |     expect(result.local).toBe(expectedLocal); | ||||||
|  |     expect(result.utc).toBe(expectedUTC); | ||||||
|   }); |   }); | ||||||
| 
 | 
 | ||||||
|   it('throws for invalid string input', () => { |   it('throws for invalid string input', () => { | ||||||
| @ -19,13 +29,21 @@ describe('epochToDate', () => { | |||||||
| }); | }); | ||||||
| 
 | 
 | ||||||
| describe('dateToEpoch', () => { | describe('dateToEpoch', () => { | ||||||
|   it('converts a known date to correct epoch (2025-06-20 13:48:00)', () => { |   it('converts a known local date to correct epoch (2025-06-20 13:48:00)', () => { | ||||||
|     const input = '2025-06-20T13:48:00'; |     const input = '2025-06-20T13:48:00'; | ||||||
|  | 
 | ||||||
|     const expectedEpoch = 1750452480; |     const expectedEpoch = 1750452480; | ||||||
|     const result = dateToEpoch(input); |     const result = dateToEpoch(input); | ||||||
|     expect(result).toBe(expectedEpoch); |     expect(result).toBe(expectedEpoch); | ||||||
|   }); |   }); | ||||||
| 
 | 
 | ||||||
|  |   it('converts a UTC date to correct epoch', () => { | ||||||
|  |     const input = '2025-06-20T13:48:00'; | ||||||
|  |     const expectedEpoch = 1750427280; | ||||||
|  |     const result = dateToEpoch(input, { parseAsUTC: true }); | ||||||
|  |     expect(result).toBe(expectedEpoch); | ||||||
|  |   }); | ||||||
|  | 
 | ||||||
|   it('throws for invalid date string', () => { |   it('throws for invalid date string', () => { | ||||||
|     expect(() => dateToEpoch('not-a-date')).toThrowError(TypeError); |     expect(() => dateToEpoch('not-a-date')).toThrowError(TypeError); | ||||||
|   }); |   }); | ||||||
| @ -34,3 +52,93 @@ describe('dateToEpoch', () => { | |||||||
|     expect(() => dateToEpoch('')).toThrowError(TypeError); |     expect(() => dateToEpoch('')).toThrowError(TypeError); | ||||||
|   }); |   }); | ||||||
| }); | }); | ||||||
|  | 
 | ||||||
|  | describe('epochToDate - Year 2038 boundary', () => { | ||||||
|  |   it('converts max 32-bit signed int epoch correctly (2038-01-19 03:14:07)', () => { | ||||||
|  |     const epoch = 2147483647; | ||||||
|  | 
 | ||||||
|  |     const result = epochToDate(epoch, { | ||||||
|  |       timeZone: 'America/Vancouver', | ||||||
|  |       locale: 'en-US', | ||||||
|  |     }); | ||||||
|  | 
 | ||||||
|  |     const expectedLocal = 'Mon, Jan 18, 2038, 19:14:07 PST'; | ||||||
|  | 
 | ||||||
|  |     const expectedUTC = 'Tue, 19 Jan 2038 03:14:07 GMT'; | ||||||
|  | 
 | ||||||
|  |     expect(result.local).toBe(expectedLocal); | ||||||
|  |     expect(result.utc).toBe(expectedUTC); | ||||||
|  |   }); | ||||||
|  | 
 | ||||||
|  |   it('handles epoch just after 32-bit boundary (2038-01-19 03:14:08)', () => { | ||||||
|  |     const epoch = 2147483648; | ||||||
|  | 
 | ||||||
|  |     const result = epochToDate(epoch, { | ||||||
|  |       timeZone: 'America/Vancouver', | ||||||
|  |       locale: 'en-US', | ||||||
|  |     }); | ||||||
|  | 
 | ||||||
|  |     const expectedLocal = 'Mon, Jan 18, 2038, 19:14:08 PST'; | ||||||
|  | 
 | ||||||
|  |     const expectedUTC = 'Tue, 19 Jan 2038 03:14:08 GMT'; | ||||||
|  | 
 | ||||||
|  |     expect(result.local).toBe(expectedLocal); | ||||||
|  |     expect(result.utc).toBe(expectedUTC); | ||||||
|  |   }); | ||||||
|  | }); | ||||||
|  | 
 | ||||||
|  | describe('dateToEpoch - Year 2038 boundary (UTC)', () => { | ||||||
|  |   it('converts "2038-01-19T03:14:07" to epoch 2147483647 in UTC mode', () => { | ||||||
|  |     const result = dateToEpoch('2038-01-19T03:14:07', { parseAsUTC: true }); | ||||||
|  |     expect(result).toBe(2147483647); | ||||||
|  |   }); | ||||||
|  | 
 | ||||||
|  |   it('converts "2038-01-19T03:14:08" to epoch 2147483648 in UTC mode', () => { | ||||||
|  |     const result = dateToEpoch('2038-01-19T03:14:08', { parseAsUTC: true }); | ||||||
|  |     expect(result).toBe(2147483648); | ||||||
|  |   }); | ||||||
|  | }); | ||||||
|  | 
 | ||||||
|  | describe('getISODateString', () => { | ||||||
|  |   it('generates a correctly padded ISO date string from date parts', () => { | ||||||
|  |     const parts: DateParts = { | ||||||
|  |       year: '2025', | ||||||
|  |       month: '6', | ||||||
|  |       day: '3', | ||||||
|  |       hour: '9', | ||||||
|  |       minute: '5', | ||||||
|  |       second: '1', | ||||||
|  |     }; | ||||||
|  | 
 | ||||||
|  |     const isoString = getISODateString(parts); | ||||||
|  |     expect(isoString).toBe('2025-06-03T09:05:01'); | ||||||
|  |   }); | ||||||
|  | 
 | ||||||
|  |   it('handles already padded inputs correctly', () => { | ||||||
|  |     const parts: DateParts = { | ||||||
|  |       year: '2025', | ||||||
|  |       month: '12', | ||||||
|  |       day: '31', | ||||||
|  |       hour: '23', | ||||||
|  |       minute: '59', | ||||||
|  |       second: '59', | ||||||
|  |     }; | ||||||
|  | 
 | ||||||
|  |     const isoString = getISODateString(parts); | ||||||
|  |     expect(isoString).toBe('2025-12-31T23:59:59'); | ||||||
|  |   }); | ||||||
|  | 
 | ||||||
|  |   it('handles all-zero input values', () => { | ||||||
|  |     const parts: DateParts = { | ||||||
|  |       year: '2025', | ||||||
|  |       month: '0', | ||||||
|  |       day: '0', | ||||||
|  |       hour: '0', | ||||||
|  |       minute: '0', | ||||||
|  |       second: '0', | ||||||
|  |     }; | ||||||
|  | 
 | ||||||
|  |     const isoString = getISODateString(parts); | ||||||
|  |     expect(isoString).toBe('2025-00-00T00:00:00'); | ||||||
|  |   }); | ||||||
|  | }); | ||||||
|  | |||||||
| @ -1,19 +1,76 @@ | |||||||
| // Convert Epoch to Human Readable Date
 | const MILLISECONDS_THRESHOLD = 1_000_000_000_000; | ||||||
| export function epochToDate(epoch: string | number): string { | const MILLISECONDS_IN_SECOND = 1000; | ||||||
|  | 
 | ||||||
|  | export interface DateParts { | ||||||
|  |   year: string | ||||||
|  |   month: string | ||||||
|  |   day: string | ||||||
|  |   hour: string | ||||||
|  |   minute: string | ||||||
|  |   second: string | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | /** | ||||||
|  |  * Converts a Unix epoch timestamp (in seconds or milliseconds) to a human-readable date. | ||||||
|  |  * | ||||||
|  |  * @param epoch - The epoch timestamp to convert (number or string). | ||||||
|  |  * @param options - Optional locale and timeZone settings for local time formatting. | ||||||
|  |  * @returns An object with both the local formatted string and UTC string. | ||||||
|  |  */ | ||||||
|  | export function epochToDate( | ||||||
|  |   epoch: string | number, | ||||||
|  |   options?: { timeZone?: string; locale?: string }, | ||||||
|  | ): { local: string; utc: string } { | ||||||
|   const num = typeof epoch === 'string' ? Number.parseInt(epoch, 10) : epoch; |   const num = typeof epoch === 'string' ? Number.parseInt(epoch, 10) : epoch; | ||||||
| 
 | 
 | ||||||
|   if (Number.isNaN(num)) { |   if (Number.isNaN(num)) { | ||||||
|     throw new TypeError('Invalid epoch timestamp'); |     throw new TypeError('Invalid epoch timestamp'); | ||||||
|   } |   } | ||||||
| 
 | 
 | ||||||
|   const timestamp = num < 1e12 ? num * 1000 : num; |   const isSecondsPrecision = num < MILLISECONDS_THRESHOLD; | ||||||
|  |   const timestampInMs = isSecondsPrecision | ||||||
|  |     ? num * MILLISECONDS_IN_SECOND | ||||||
|  |     : num; | ||||||
| 
 | 
 | ||||||
|   return new Date(timestamp).toLocaleString(); |   const date = new Date(timestampInMs); | ||||||
|  | 
 | ||||||
|  |   const local = date.toLocaleString(options?.locale || 'en-US', { | ||||||
|  |     timeZone: options?.timeZone, | ||||||
|  |     weekday: 'short', | ||||||
|  |     year: 'numeric', | ||||||
|  |     month: 'short', | ||||||
|  |     day: '2-digit', | ||||||
|  |     hour: '2-digit', | ||||||
|  |     minute: '2-digit', | ||||||
|  |     second: '2-digit', | ||||||
|  |     hour12: false, | ||||||
|  |     timeZoneName: 'short', | ||||||
|  |   }); | ||||||
|  | 
 | ||||||
|  |   const utc = date.toUTCString(); | ||||||
|  | 
 | ||||||
|  |   return { local, utc }; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| // Convert Human Readable Date to Epoch
 | /** | ||||||
| export function dateToEpoch(dateString: string): number { |  * Converts a human-readable ISO date string into a Unix epoch timestamp (in seconds). | ||||||
|   const date = new Date(dateString); |  * | ||||||
|  |  * @param dateString - A string in ISO format (e.g. "2025-06-20T13:48:00"). | ||||||
|  |  * @param options - Optional flag to interpret the date string as UTC time. | ||||||
|  |  * @returns Epoch time as a number in seconds. | ||||||
|  |  */ | ||||||
|  | export function dateToEpoch( | ||||||
|  |   dateString: string, | ||||||
|  |   options?: { | ||||||
|  |     parseAsUTC?: boolean // if true, the date string will be parsed as UTC
 | ||||||
|  |   }, | ||||||
|  | ): number { | ||||||
|  |   const shouldNormalizeToUTC = options?.parseAsUTC === true && !dateString.endsWith('Z'); | ||||||
|  |   const normalizedDateString = shouldNormalizeToUTC | ||||||
|  |     ? `${dateString}Z` | ||||||
|  |     : dateString; | ||||||
|  | 
 | ||||||
|  |   const date = new Date(normalizedDateString); | ||||||
| 
 | 
 | ||||||
|   if (Number.isNaN(date.getTime())) { |   if (Number.isNaN(date.getTime())) { | ||||||
|     throw new TypeError('Invalid date string'); |     throw new TypeError('Invalid date string'); | ||||||
| @ -21,3 +78,22 @@ export function dateToEpoch(dateString: string): number { | |||||||
| 
 | 
 | ||||||
|   return Math.floor(date.getTime() / 1000); |   return Math.floor(date.getTime() / 1000); | ||||||
| } | } | ||||||
|  | 
 | ||||||
|  | /** | ||||||
|  |  * Creates an ISO 8601 date string (e.g., "2025-06-20T13:48:00") from date parts. | ||||||
|  |  * Ensures all components are zero-padded to 2 digits. | ||||||
|  |  * | ||||||
|  |  * @param parts - An object containing the year, month, day, hour, minute, and second. | ||||||
|  |  * @returns A valid ISO string. | ||||||
|  |  */ | ||||||
|  | export function getISODateString({ | ||||||
|  |   year, | ||||||
|  |   month, | ||||||
|  |   day, | ||||||
|  |   hour, | ||||||
|  |   minute, | ||||||
|  |   second, | ||||||
|  | }: DateParts): string { | ||||||
|  |   const pad = (value: string) => value.toString().padStart(2, '0'); | ||||||
|  |   return `${year}-${pad(month)}-${pad(day)}T${pad(hour)}:${pad(minute)}:${pad(second)}`; | ||||||
|  | } | ||||||
|  | |||||||
| @ -1,13 +1,16 @@ | |||||||
| <script setup lang="ts"> | <script setup lang="ts"> | ||||||
| import { ref } from 'vue'; | import { ref } from 'vue'; | ||||||
| import { dateToEpoch, epochToDate } from './epoch-converter.service.ts'; | import { type DateParts, dateToEpoch, epochToDate, getISODateString } from './epoch-converter.service.ts'; | ||||||
| 
 | 
 | ||||||
| const epochInput = ref(''); | const epochInput = ref(''); | ||||||
| const dateOutput = ref(''); | const dateOutput = ref<{ local: string; utc: string } | null>(null); | ||||||
| const epochOutput = ref(''); | const epochOutput = ref(''); | ||||||
| const error = ref<string | null>(null); | const error = ref<string | null>(null); | ||||||
| 
 | 
 | ||||||
| const dateParts = ref({ | const epochInputError = ref<string | null>(null); | ||||||
|  | const dateInputError = ref<string | null>(null); | ||||||
|  | 
 | ||||||
|  | const dateParts = ref<DateParts>({ | ||||||
|   year: '', |   year: '', | ||||||
|   month: '', |   month: '', | ||||||
|   day: '', |   day: '', | ||||||
| @ -16,32 +19,84 @@ const dateParts = ref({ | |||||||
|   second: '', |   second: '', | ||||||
| }); | }); | ||||||
| 
 | 
 | ||||||
|  | /** | ||||||
|  |  * Converts a Unix epoch timestamp to human-readable date strings | ||||||
|  |  * Accepts seconds (10-digit) or milliseconds (13-digit) | ||||||
|  |  */ | ||||||
| function convertEpochToDate() { | function convertEpochToDate() { | ||||||
|   error.value = null; |   error.value = null; | ||||||
|   try { |   try { | ||||||
|     dateOutput.value = epochToDate(epochInput.value); |     dateOutput.value = epochToDate(epochInput.value); | ||||||
|   } |   } | ||||||
|   catch (e: any) { |   catch (e: any) { | ||||||
|     error.value = e.message; |     epochInputError.value = e.message; | ||||||
|   } |   } | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| function convertDateToEpoch() { | /** | ||||||
|   error.value = null; |  * Converts a Unix epoch timestamp to human-readable date strings | ||||||
|  |  * Accepts seconds (10-digit) or milliseconds (13-digit) | ||||||
|  |  */ | ||||||
|  | function convertDateToEpochLocal() { | ||||||
|   try { |   try { | ||||||
|     const { year, month, day, hour, minute, second } = dateParts.value; |     validateDateParts(dateParts.value); | ||||||
| 
 |     const isoString = getISODateString(dateParts.value); | ||||||
|     const isoString = `${year}-${pad(month)}-${pad(day)}T${pad(hour)}:${pad(minute)}:${pad(second)}`; |  | ||||||
|     epochOutput.value = dateToEpoch(isoString); |     epochOutput.value = dateToEpoch(isoString); | ||||||
|  |     dateInputError.value = null; | ||||||
|   } |   } | ||||||
|   catch (e: any) { |   catch (e: any) { | ||||||
|     error.value = e.message; |     epochOutput.value = ''; | ||||||
|  |     dateInputError.value = e.message; | ||||||
|   } |   } | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| function pad(value: string): string { | /** | ||||||
|   return value.toString().padStart(2, '0'); |  * Converts UTC date string parts to epoch (seconds) | ||||||
|  |  */ | ||||||
|  | function convertDateToEpochUTC() { | ||||||
|  |   try { | ||||||
|  |     validateDateParts(dateParts.value); | ||||||
|  |     const isoString = getISODateString(dateParts.value); | ||||||
|  |     epochOutput.value = dateToEpoch(isoString, { utc: true }); | ||||||
|  |     dateInputError.value = null; | ||||||
|  |   } | ||||||
|  |   catch (e: any) { | ||||||
|  |     epochOutput.value = ''; | ||||||
|  |     dateInputError.value = e.message; | ||||||
|  |   } | ||||||
| } | } | ||||||
|  | 
 | ||||||
|  | function validateDateParts(parts: DateParts): void { | ||||||
|  |   const { year, month, day, hour, minute, second } = parts; | ||||||
|  | 
 | ||||||
|  |   if (!/^\d{4}$/.test(year)) { | ||||||
|  |     throw new Error('Year must be 4 digits'); | ||||||
|  |   } | ||||||
|  |   if (+month < 1 || +month > 12) { | ||||||
|  |     throw new Error('Month must be between 1 and 12'); | ||||||
|  |   } | ||||||
|  |   if (+day < 1 || +day > 31) { | ||||||
|  |     throw new Error('Day must be between 1 and 31'); | ||||||
|  |   } | ||||||
|  |   if (+hour < 0 || +hour > 23) { | ||||||
|  |     throw new Error('Hour must be between 0 and 23'); | ||||||
|  |   } | ||||||
|  |   if (+minute < 0 || +minute > 59) { | ||||||
|  |     throw new Error('Minute must be between 0 and 59'); | ||||||
|  |   } | ||||||
|  |   if (+second < 0 || +second > 59) { | ||||||
|  |     throw new Error('Second must be between 0 and 59'); | ||||||
|  |   } | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // Clear errors on input | ||||||
|  | watch(epochInput, () => { | ||||||
|  |   epochInputError.value = null; | ||||||
|  | }); | ||||||
|  | 
 | ||||||
|  | watch(dateParts, () => { | ||||||
|  |   dateInputError.value = null; | ||||||
|  | }, { deep: true }); | ||||||
| </script> | </script> | ||||||
| 
 | 
 | ||||||
| <template> | <template> | ||||||
| @ -51,6 +106,16 @@ function pad(value: string): string { | |||||||
|       <div class="mb-2 font-semibold"> |       <div class="mb-2 font-semibold"> | ||||||
|         Epoch to Date |         Epoch to Date | ||||||
|       </div> |       </div> | ||||||
|  | 
 | ||||||
|  |       <div class="mb-2 text-xs text-neutral-400"> | ||||||
|  |         Epoch is interpreted as: | ||||||
|  |         <ul class="mt-1 list-disc pl-4"> | ||||||
|  |           <li><strong>10 digits</strong> → seconds (e.g. <code>1718822594</code>)</li> | ||||||
|  |           <li><strong>13 digits</strong> → milliseconds (e.g. <code>1718822594000</code>)</li> | ||||||
|  |         </ul> | ||||||
|  |         Epoch values outside supported JavaScript range (±8.64e15) may result in invalid dates. | ||||||
|  |       </div> | ||||||
|  | 
 | ||||||
|       <c-input-text |       <c-input-text | ||||||
|         v-model:value="epochInput" |         v-model:value="epochInput" | ||||||
|         placeholder="Enter epoch timestamp (e.g. 1718822594)" |         placeholder="Enter epoch timestamp (e.g. 1718822594)" | ||||||
| @ -61,11 +126,16 @@ function pad(value: string): string { | |||||||
|         Convert to Date |         Convert to Date | ||||||
|       </c-button> |       </c-button> | ||||||
| 
 | 
 | ||||||
|       <div v-if="dateOutput" class="mt-4 text-sm text-green-400"> |       <div v-if="dateOutput" class="mt-4 text-sm text-green-400 space-y-1"> | ||||||
|         Human-Readable Date: <strong>{{ dateOutput }}</strong> |         <div>Local Time: <strong>{{ dateOutput.local }}</strong></div> | ||||||
|  |         <div>GMT (UTC): <strong>{{ dateOutput.utc }}</strong></div> | ||||||
|       </div> |       </div> | ||||||
|     </div> |     </div> | ||||||
| 
 | 
 | ||||||
|  |     <c-alert v-if="epochInputError" type="error" class="mb-4 mt-4"> | ||||||
|  |       {{ epochInputError }} | ||||||
|  |     </c-alert> | ||||||
|  | 
 | ||||||
|     <!-- Date to Epoch --> |     <!-- Date to Epoch --> | ||||||
|     <div class="mb-8"> |     <div class="mb-8"> | ||||||
|       <div class="mb-2 font-semibold"> |       <div class="mb-2 font-semibold"> | ||||||
| @ -99,17 +169,22 @@ function pad(value: string): string { | |||||||
|         </div> |         </div> | ||||||
|       </div> |       </div> | ||||||
| 
 | 
 | ||||||
|       <c-button @click="convertDateToEpoch"> |       <div class="mt-2 flex gap-4"> | ||||||
|         Convert to Epoch |         <c-button @click="convertDateToEpochLocal"> | ||||||
|       </c-button> |           Convert to Epoch (Local) | ||||||
|  |         </c-button> | ||||||
|  |         <c-button @click="convertDateToEpochUTC"> | ||||||
|  |           Convert to Epoch (UTC) | ||||||
|  |         </c-button> | ||||||
|  |       </div> | ||||||
| 
 | 
 | ||||||
|       <div v-if="epochOutput" class="mt-4 text-sm text-green-400"> |       <div v-if="epochOutput" class="mt-4 text-sm text-green-400"> | ||||||
|         Epoch Timestamp: <strong>{{ epochOutput }}</strong> |         Epoch Timestamp: <strong>{{ epochOutput }}</strong> | ||||||
|       </div> |       </div> | ||||||
|     </div> |     </div> | ||||||
| 
 | 
 | ||||||
|     <c-alert v-if="error" type="error" class="mt-6"> |     <c-alert v-if="dateInputError" type="error" class="mb-4 mt-4"> | ||||||
|       {{ error }} |       {{ dateInputError }} | ||||||
|     </c-alert> |     </c-alert> | ||||||
|   </c-card> |   </c-card> | ||||||
| </template> | </template> | ||||||
|  | |||||||
| @ -1,6 +1,7 @@ | |||||||
| import { tool as base64FileConverter } from './base64-file-converter'; | import { tool as base64FileConverter } from './base64-file-converter'; | ||||||
| import { tool as base64StringConverter } from './base64-string-converter'; | import { tool as base64StringConverter } from './base64-string-converter'; | ||||||
| import { tool as basicAuthGenerator } from './basic-auth-generator'; | import { tool as basicAuthGenerator } from './basic-auth-generator'; | ||||||
|  | import { tool as gzipDecompressor } from './gzip-decompressor'; | ||||||
| import { tool as epochConverter } from './epoch-converter'; | import { tool as epochConverter } from './epoch-converter'; | ||||||
| import { tool as emailNormalizer } from './email-normalizer'; | import { tool as emailNormalizer } from './email-normalizer'; | ||||||
| 
 | 
 | ||||||
|  | |||||||
		Loading…
	
		Reference in New Issue
	
	Block a user