From 2b79dabbebb44172e58a8454d64dbf8588921267 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Thu, 10 Jul 2025 07:25:00 +0000 Subject: [PATCH] Add epoch to date conversion mode with radio button selection Co-authored-by: CryoRig <9450688+CryoRig@users.noreply.github.com> --- .../convert-date-to-epoch.service.test.ts | 86 ++++++++++++++- .../time/convert-date-to-epoch/index.tsx | 100 ++++++++++++------ .../tools/time/convert-date-to-epoch/meta.ts | 16 ++- .../time/convert-date-to-epoch/service.ts | 42 ++++++++ .../tools/time/convert-date-to-epoch/types.ts | 3 + 5 files changed, 211 insertions(+), 36 deletions(-) create mode 100644 src/pages/tools/time/convert-date-to-epoch/types.ts diff --git a/src/pages/tools/time/convert-date-to-epoch/convert-date-to-epoch.service.test.ts b/src/pages/tools/time/convert-date-to-epoch/convert-date-to-epoch.service.test.ts index 33d6424..c5624a5 100644 --- a/src/pages/tools/time/convert-date-to-epoch/convert-date-to-epoch.service.test.ts +++ b/src/pages/tools/time/convert-date-to-epoch/convert-date-to-epoch.service.test.ts @@ -1,5 +1,5 @@ import { describe, it, expect } from 'vitest'; -import { convertDateToEpoch } from './service'; +import { convertDateToEpoch, convertEpochToDate } from './service'; describe('convertDateToEpoch', () => { it('should convert ISO 8601 date strings to epoch', () => { @@ -107,3 +107,87 @@ describe('convertDateToEpoch', () => { expect(result).toBe('1672531200'); }); }); + +describe('convertEpochToDate', () => { + it('should convert epoch timestamps to human-readable dates', () => { + const input = '1672531200\n1704067199'; + const result = convertEpochToDate(input); + const lines = result.split('\n'); + + expect(lines[0]).toBe('2023-01-01 00:00:00 UTC'); + expect(lines[1]).toBe('2023-12-31 23:59:59 UTC'); + }); + + it('should convert single epoch timestamp', () => { + const input = '1672531200'; + const result = convertEpochToDate(input); + + expect(result).toBe('2023-01-01 00:00:00 UTC'); + }); + + it('should handle epoch timestamp 0', () => { + const input = '0'; + const result = convertEpochToDate(input); + + expect(result).toBe('1970-01-01 00:00:00 UTC'); + }); + + it('should handle empty lines', () => { + const input = '1672531200\n\n1704067199'; + const result = convertEpochToDate(input); + const lines = result.split('\n'); + + expect(lines[0]).toBe('2023-01-01 00:00:00 UTC'); + expect(lines[1]).toBe(''); + expect(lines[2]).toBe('2023-12-31 23:59:59 UTC'); + }); + + it('should handle empty input', () => { + const input = ''; + const result = convertEpochToDate(input); + + expect(result).toBe(''); + }); + + it('should throw error for invalid epoch timestamp', () => { + const input = 'invalid-epoch'; + + expect(() => convertEpochToDate(input)).toThrow( + 'Invalid epoch timestamp on line 1: "invalid-epoch"' + ); + }); + + it('should throw error for negative epoch timestamp', () => { + const input = '-1672531200'; + + expect(() => convertEpochToDate(input)).toThrow( + 'Invalid epoch timestamp on line 1: "-1672531200"' + ); + }); + + it('should throw error for epoch timestamp too far in the future', () => { + const input = '9999999999'; + + expect(() => convertEpochToDate(input)).toThrow( + 'Invalid epoch timestamp on line 1: "9999999999"' + ); + }); + + it('should handle multiple epoch timestamps', () => { + const input = '0\n946684800\n1577836800'; + const result = convertEpochToDate(input); + const lines = result.split('\n'); + + expect(lines[0]).toBe('1970-01-01 00:00:00 UTC'); + expect(lines[1]).toBe('2000-01-01 00:00:00 UTC'); + expect(lines[2]).toBe('2020-01-01 00:00:00 UTC'); + }); + + it('should throw error for invalid epoch on specific line', () => { + const input = '1672531200\ninvalid-epoch\n1704067199'; + + expect(() => convertEpochToDate(input)).toThrow( + 'Invalid epoch timestamp on line 2: "invalid-epoch"' + ); + }); +}); diff --git a/src/pages/tools/time/convert-date-to-epoch/index.tsx b/src/pages/tools/time/convert-date-to-epoch/index.tsx index df5b510..f112b90 100644 --- a/src/pages/tools/time/convert-date-to-epoch/index.tsx +++ b/src/pages/tools/time/convert-date-to-epoch/index.tsx @@ -4,14 +4,19 @@ import { ToolComponentProps } from '@tools/defineTool'; import ToolTextInput from '@components/input/ToolTextInput'; import ToolTextResult from '@components/result/ToolTextResult'; import { CardExampleType } from '@components/examples/ToolExamples'; -import { convertDateToEpoch } from './service'; +import { GetGroupsType } from '@components/options/ToolOptions'; +import { Box } from '@mui/material'; +import SimpleRadio from '@components/options/SimpleRadio'; +import { convertDateToEpoch, convertEpochToDate } from './service'; +import { InitialValuesType } from './types'; -const initialValues = {}; -type InitialValuesType = typeof initialValues; +const initialValues: InitialValuesType = { + mode: 'dateToEpoch' +}; const exampleCards: CardExampleType[] = [ { - title: 'ISO 8601 Dates', + title: 'ISO 8601 Dates to Epoch', description: 'Convert standard ISO 8601 formatted dates to epoch timestamps. This format is commonly used in APIs and data exchange.', sampleText: `2023-01-01T00:00:00Z @@ -20,10 +25,10 @@ const exampleCards: CardExampleType[] = [ sampleResult: `1672531200 1686832245 1704067199`, - sampleOptions: {} + sampleOptions: { mode: 'dateToEpoch' } }, { - title: 'Common Date Formats', + title: 'Common Date Formats to Epoch', description: 'Convert various common date formats including YYYY-MM-DD, MM/DD/YYYY, and DD/MM/YYYY to epoch timestamps.', sampleText: `2023-01-01 @@ -34,33 +39,33 @@ const exampleCards: CardExampleType[] = [ 1673740800 1686787200 1703961800`, - sampleOptions: {} + sampleOptions: { mode: 'dateToEpoch' } }, { - title: 'Mixed Date Formats', + title: 'Epoch to Human-Readable Dates', description: - 'The tool automatically detects and converts various date formats in a single input, making it easy to process mixed date data.', - sampleText: `2023-01-01T00:00:00Z -01/15/2023 14:30 -2023-06-15 -12/31/2023 23:59:59`, - sampleResult: `1672531200 -1673792200 -1686787200 -1704063599`, - sampleOptions: {} - }, - { - title: 'Existing Epoch Timestamps', - description: - 'If you input existing epoch timestamps, the tool validates them and passes them through unchanged.', + 'Convert Unix epoch timestamps back to human-readable date format. The output format is YYYY-MM-DD HH:mm:ss UTC.', sampleText: `1672531200 -1686787200 +1686832245 1704067199`, - sampleResult: `1672531200 -1686787200 -1704067199`, - sampleOptions: {} + sampleResult: `2023-01-01 00:00:00 UTC +2023-06-15 12:30:45 UTC +2023-12-31 23:59:59 UTC`, + sampleOptions: { mode: 'epochToDate' } + }, + { + title: 'Mixed Epoch Timestamps', + description: + 'Convert multiple epoch timestamps from different years and times to readable dates.', + sampleText: `0 +946684800 +1577836800 +1735689600`, + sampleResult: `1970-01-01 00:00:00 UTC +2000-01-01 00:00:00 UTC +2020-01-01 00:00:00 UTC +2025-01-01 00:00:00 UTC`, + sampleOptions: { mode: 'epochToDate' } } ]; @@ -71,10 +76,43 @@ export default function ConvertDateToEpoch({ const [input, setInput] = useState(''); const [result, setResult] = useState(''); - const compute = (optionsValues: typeof initialValues, input: string) => { - setResult(convertDateToEpoch(input)); + const compute = (optionsValues: InitialValuesType, input: string) => { + if (optionsValues.mode === 'dateToEpoch') { + setResult(convertDateToEpoch(input)); + } else { + setResult(convertEpochToDate(input)); + } }; + const getGroups: GetGroupsType = ({ + values, + updateField + }) => [ + { + title: 'Conversion Mode', + component: ( + + updateField('mode', 'dateToEpoch')} + checked={values.mode === 'dateToEpoch'} + title={'Date to Epoch'} + description={ + 'Convert human-readable dates to Unix epoch timestamps' + } + /> + updateField('mode', 'epochToDate')} + checked={values.mode === 'epochToDate'} + title={'Epoch to Date'} + description={ + 'Convert Unix epoch timestamps to human-readable dates' + } + /> + + ) + } + ]; + return ( } resultComponent={} initialValues={initialValues} - getGroups={null} + getGroups={getGroups} setInput={setInput} compute={compute} toolInfo={{ title: `What is a ${title}?`, description: longDescription }} diff --git a/src/pages/tools/time/convert-date-to-epoch/meta.ts b/src/pages/tools/time/convert-date-to-epoch/meta.ts index 556fd6e..9ed825d 100644 --- a/src/pages/tools/time/convert-date-to-epoch/meta.ts +++ b/src/pages/tools/time/convert-date-to-epoch/meta.ts @@ -6,10 +6,18 @@ export const tool = defineTool('time', { name: 'Convert Date to Epoch', icon: 'ic:round-schedule', description: - 'Convert dates and times to Unix epoch timestamps (seconds since January 1, 1970 UTC). This tool supports multiple date formats including ISO 8601, MM/DD/YYYY, DD/MM/YYYY, and YYYY-MM-DD formats. Perfect for converting human-readable dates to Unix timestamps for programming and database usage.', - shortDescription: 'Convert dates to Unix epoch timestamps.', - keywords: ['convert', 'epoch', 'unix', 'timestamp', 'date', 'time'], + 'Convert between dates and Unix epoch timestamps bidirectionally. This tool supports converting human-readable dates to Unix epoch timestamps (seconds since January 1, 1970 UTC) and vice versa. It handles multiple date formats including ISO 8601, MM/DD/YYYY, DD/MM/YYYY, and YYYY-MM-DD formats. Perfect for converting between human-readable dates and Unix timestamps for programming and database usage.', + shortDescription: 'Convert between dates and Unix epoch timestamps.', + keywords: [ + 'convert', + 'epoch', + 'unix', + 'timestamp', + 'date', + 'time', + 'bidirectional' + ], longDescription: - 'This is a quick online utility for converting dates and times to Unix epoch timestamps. Unix epoch time is the number of seconds that have elapsed since January 1, 1970, at 00:00:00 UTC. This tool supports various date formats including ISO 8601 (YYYY-MM-DDTHH:mm:ssZ), YYYY-MM-DD, MM/DD/YYYY, DD/MM/YYYY, and many other common formats. You can input multiple dates (one per line) and the tool will convert each to its corresponding epoch timestamp. If you input an existing epoch timestamp, it will be validated and passed through. The tool automatically handles timezone conversions to UTC for accurate epoch calculation. This is particularly useful for developers working with databases, APIs, or any system that stores dates as Unix timestamps.', + 'This is a quick online utility for converting between dates and Unix epoch timestamps bidirectionally. Unix epoch time is the number of seconds that have elapsed since January 1, 1970, at 00:00:00 UTC. This tool supports two modes: Date to Epoch and Epoch to Date. In Date to Epoch mode, it converts various date formats including ISO 8601 (YYYY-MM-DDTHH:mm:ssZ), YYYY-MM-DD, MM/DD/YYYY, DD/MM/YYYY, and many other common formats to Unix timestamps. In Epoch to Date mode, it converts Unix epoch timestamps back to human-readable dates in YYYY-MM-DD HH:mm:ss UTC format. You can input multiple values (one per line) and the tool will convert each accordingly. The tool automatically handles timezone conversions to UTC for accurate epoch calculation and provides clear error messages for invalid inputs. This is particularly useful for developers working with databases, APIs, or any system that stores dates as Unix timestamps.', component: lazy(() => import('./index')) }); diff --git a/src/pages/tools/time/convert-date-to-epoch/service.ts b/src/pages/tools/time/convert-date-to-epoch/service.ts index d5932fa..3f7a8dd 100644 --- a/src/pages/tools/time/convert-date-to-epoch/service.ts +++ b/src/pages/tools/time/convert-date-to-epoch/service.ts @@ -76,6 +76,36 @@ function convertSingleDateToEpoch( return parsedDate.utc().unix().toString(); } +function convertSingleEpochToDate( + epochString: string, + lineNumber: number +): string { + if (epochString.trim() === '') { + return ''; + } + + const trimmedInput = epochString.trim(); + + // Check if it's a valid epoch timestamp (all digits) + if (!/^\d+$/.test(trimmedInput)) { + throw new Error( + `Invalid epoch timestamp on line ${lineNumber}: "${epochString}"` + ); + } + + const timestamp = parseInt(trimmedInput, 10); + + // Check if it's a reasonable timestamp (not negative and not too far in the future) + if (timestamp < 0 || timestamp > 4102444800) { + throw new Error( + `Invalid epoch timestamp on line ${lineNumber}: "${epochString}"` + ); + } + + // Convert epoch to human-readable date in ISO format + return dayjs.unix(timestamp).utc().format('YYYY-MM-DD HH:mm:ss UTC'); +} + export function convertDateToEpoch(input: string): string { const result: string[] = []; const lines = input.split('\n'); @@ -87,3 +117,15 @@ export function convertDateToEpoch(input: string): string { return result.join('\n'); } + +export function convertEpochToDate(input: string): string { + const result: string[] = []; + const lines = input.split('\n'); + + lines.forEach((line, index) => { + const date = convertSingleEpochToDate(line, index + 1); + result.push(date); + }); + + return result.join('\n'); +} diff --git a/src/pages/tools/time/convert-date-to-epoch/types.ts b/src/pages/tools/time/convert-date-to-epoch/types.ts new file mode 100644 index 0000000..cf5cc01 --- /dev/null +++ b/src/pages/tools/time/convert-date-to-epoch/types.ts @@ -0,0 +1,3 @@ +export type InitialValuesType = { + mode: 'dateToEpoch' | 'epochToDate'; +};