mirror of
https://github.com/iib0011/omni-tools.git
synced 2025-11-06 00:44:57 +05:30
Merge pull request #2 from CryoRig/copilot/fix-1
Add Time converter to epoch and reverse
This commit is contained in:
commit
9c45f2492a
6 changed files with 482 additions and 0 deletions
|
|
@ -0,0 +1,193 @@
|
|||
import { describe, it, expect } from 'vitest';
|
||||
import { convertDateToEpoch, convertEpochToDate } from './service';
|
||||
|
||||
describe('convertDateToEpoch', () => {
|
||||
it('should convert ISO 8601 date strings to epoch', () => {
|
||||
const input = '2023-01-01T00:00:00Z\n2023-12-31T23:59:59Z';
|
||||
const result = convertDateToEpoch(input);
|
||||
const lines = result.split('\n');
|
||||
|
||||
expect(lines[0]).toBe('1672531200'); // 2023-01-01 00:00:00 UTC
|
||||
expect(lines[1]).toBe('1704067199'); // 2023-12-31 23:59:59 UTC
|
||||
});
|
||||
|
||||
it('should convert YYYY-MM-DD date format to epoch', () => {
|
||||
const input = '2023-01-01\n2023-06-15';
|
||||
const result = convertDateToEpoch(input);
|
||||
const lines = result.split('\n');
|
||||
|
||||
expect(lines[0]).toBe('1672531200'); // 2023-01-01 00:00:00 UTC
|
||||
expect(lines[1]).toBe('1686787200'); // 2023-06-15 00:00:00 UTC
|
||||
});
|
||||
|
||||
it('should convert YYYY-MM-DD HH:mm:ss format to epoch', () => {
|
||||
const input = '2023-01-01 12:30:45';
|
||||
const result = convertDateToEpoch(input);
|
||||
|
||||
expect(result).toBe('1672576245'); // 2023-01-01 12:30:45 UTC
|
||||
});
|
||||
|
||||
it('should convert MM/DD/YYYY format to epoch', () => {
|
||||
const input = '01/01/2023\n12/31/2023';
|
||||
const result = convertDateToEpoch(input);
|
||||
const lines = result.split('\n');
|
||||
|
||||
expect(lines[0]).toBe('1672531200'); // 2023-01-01 00:00:00 UTC
|
||||
expect(lines[1]).toBe('1703980800'); // 2023-12-31 00:00:00 UTC
|
||||
});
|
||||
|
||||
it('should convert DD/MM/YYYY format to epoch', () => {
|
||||
const input = '15/06/2023';
|
||||
const result = convertDateToEpoch(input);
|
||||
|
||||
expect(result).toBe('1686787200'); // 2023-06-15 00:00:00 UTC
|
||||
});
|
||||
|
||||
it('should handle already existing epoch timestamps', () => {
|
||||
const input = '1672531200\n1704067199';
|
||||
const result = convertDateToEpoch(input);
|
||||
|
||||
expect(result).toBe('1672531200\n1704067199');
|
||||
});
|
||||
|
||||
it('should handle empty lines', () => {
|
||||
const input = '2023-01-01\n\n2023-12-31';
|
||||
const result = convertDateToEpoch(input);
|
||||
const lines = result.split('\n');
|
||||
|
||||
expect(lines[0]).toBe('1672531200');
|
||||
expect(lines[1]).toBe('');
|
||||
expect(lines[2]).toBe('1703980800');
|
||||
});
|
||||
|
||||
it('should handle empty input', () => {
|
||||
const input = '';
|
||||
const result = convertDateToEpoch(input);
|
||||
|
||||
expect(result).toBe('');
|
||||
});
|
||||
|
||||
it('should throw error for invalid date format', () => {
|
||||
const input = 'invalid-date-format';
|
||||
|
||||
expect(() => convertDateToEpoch(input)).toThrow(
|
||||
'Invalid date format on line 1: "invalid-date-format"'
|
||||
);
|
||||
});
|
||||
|
||||
it('should throw error for invalid date on specific line', () => {
|
||||
const input = '2023-01-01\ninvalid-date\n2023-12-31';
|
||||
|
||||
expect(() => convertDateToEpoch(input)).toThrow(
|
||||
'Invalid date format on line 2: "invalid-date"'
|
||||
);
|
||||
});
|
||||
|
||||
it('should handle mixed date formats', () => {
|
||||
const input = '2023-01-01T00:00:00Z\n01/15/2023\n2023-06-15 12:30:00';
|
||||
const result = convertDateToEpoch(input);
|
||||
const lines = result.split('\n');
|
||||
|
||||
expect(lines[0]).toBe('1672531200'); // ISO format
|
||||
expect(lines[1]).toBe('1673740800'); // MM/DD/YYYY format
|
||||
expect(lines[2]).toBe('1686832200'); // YYYY-MM-DD HH:mm:ss format
|
||||
});
|
||||
|
||||
it('should handle JavaScript date string format', () => {
|
||||
const input = 'Sun Jan 01 2023 00:00:00';
|
||||
const result = convertDateToEpoch(input);
|
||||
|
||||
expect(result).toBe('1672531200');
|
||||
});
|
||||
|
||||
it('should convert date with milliseconds correctly', () => {
|
||||
const input = '2023-01-01T00:00:00.000Z';
|
||||
const result = convertDateToEpoch(input);
|
||||
|
||||
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"'
|
||||
);
|
||||
});
|
||||
});
|
||||
130
src/pages/tools/time/convert-date-to-epoch/index.tsx
Normal file
130
src/pages/tools/time/convert-date-to-epoch/index.tsx
Normal file
|
|
@ -0,0 +1,130 @@
|
|||
import React, { useState } from 'react';
|
||||
import ToolContent from '@components/ToolContent';
|
||||
import { ToolComponentProps } from '@tools/defineTool';
|
||||
import ToolTextInput from '@components/input/ToolTextInput';
|
||||
import ToolTextResult from '@components/result/ToolTextResult';
|
||||
import { CardExampleType } from '@components/examples/ToolExamples';
|
||||
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: InitialValuesType = {
|
||||
mode: 'dateToEpoch'
|
||||
};
|
||||
|
||||
const exampleCards: CardExampleType<InitialValuesType>[] = [
|
||||
{
|
||||
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
|
||||
2023-06-15T12:30:45Z
|
||||
2023-12-31T23:59:59Z`,
|
||||
sampleResult: `1672531200
|
||||
1686832245
|
||||
1704067199`,
|
||||
sampleOptions: { mode: 'dateToEpoch' }
|
||||
},
|
||||
{
|
||||
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
|
||||
01/15/2023
|
||||
15/06/2023
|
||||
2023-12-31 18:30:00`,
|
||||
sampleResult: `1672531200
|
||||
1673740800
|
||||
1686787200
|
||||
1703961800`,
|
||||
sampleOptions: { mode: 'dateToEpoch' }
|
||||
},
|
||||
{
|
||||
title: 'Epoch to Human-Readable Dates',
|
||||
description:
|
||||
'Convert Unix epoch timestamps back to human-readable date format. The output format is YYYY-MM-DD HH:mm:ss UTC.',
|
||||
sampleText: `1672531200
|
||||
1686832245
|
||||
1704067199`,
|
||||
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' }
|
||||
}
|
||||
];
|
||||
|
||||
export default function ConvertDateToEpoch({
|
||||
title,
|
||||
longDescription
|
||||
}: ToolComponentProps) {
|
||||
const [input, setInput] = useState<string>('');
|
||||
const [result, setResult] = useState<string>('');
|
||||
|
||||
const compute = (optionsValues: InitialValuesType, input: string) => {
|
||||
if (optionsValues.mode === 'dateToEpoch') {
|
||||
setResult(convertDateToEpoch(input));
|
||||
} else {
|
||||
setResult(convertEpochToDate(input));
|
||||
}
|
||||
};
|
||||
|
||||
const getGroups: GetGroupsType<InitialValuesType> = ({
|
||||
values,
|
||||
updateField
|
||||
}) => [
|
||||
{
|
||||
title: 'Conversion Mode',
|
||||
component: (
|
||||
<Box>
|
||||
<SimpleRadio
|
||||
onClick={() => updateField('mode', 'dateToEpoch')}
|
||||
checked={values.mode === 'dateToEpoch'}
|
||||
title={'Date to Epoch'}
|
||||
description={
|
||||
'Convert human-readable dates to Unix epoch timestamps'
|
||||
}
|
||||
/>
|
||||
<SimpleRadio
|
||||
onClick={() => updateField('mode', 'epochToDate')}
|
||||
checked={values.mode === 'epochToDate'}
|
||||
title={'Epoch to Date'}
|
||||
description={
|
||||
'Convert Unix epoch timestamps to human-readable dates'
|
||||
}
|
||||
/>
|
||||
</Box>
|
||||
)
|
||||
}
|
||||
];
|
||||
|
||||
return (
|
||||
<ToolContent
|
||||
title={title}
|
||||
input={input}
|
||||
inputComponent={<ToolTextInput value={input} onChange={setInput} />}
|
||||
resultComponent={<ToolTextResult value={result} />}
|
||||
initialValues={initialValues}
|
||||
getGroups={getGroups}
|
||||
setInput={setInput}
|
||||
compute={compute}
|
||||
toolInfo={{ title: `What is a ${title}?`, description: longDescription }}
|
||||
exampleCards={exampleCards}
|
||||
/>
|
||||
);
|
||||
}
|
||||
23
src/pages/tools/time/convert-date-to-epoch/meta.ts
Normal file
23
src/pages/tools/time/convert-date-to-epoch/meta.ts
Normal file
|
|
@ -0,0 +1,23 @@
|
|||
import { defineTool } from '@tools/defineTool';
|
||||
import { lazy } from 'react';
|
||||
|
||||
export const tool = defineTool('time', {
|
||||
path: 'convert-date-to-epoch',
|
||||
name: 'Convert Date to Epoch',
|
||||
icon: 'ic:round-schedule',
|
||||
description:
|
||||
'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 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'))
|
||||
});
|
||||
131
src/pages/tools/time/convert-date-to-epoch/service.ts
Normal file
131
src/pages/tools/time/convert-date-to-epoch/service.ts
Normal file
|
|
@ -0,0 +1,131 @@
|
|||
import dayjs from 'dayjs';
|
||||
import utc from 'dayjs/plugin/utc';
|
||||
import customParseFormat from 'dayjs/plugin/customParseFormat';
|
||||
|
||||
dayjs.extend(utc);
|
||||
dayjs.extend(customParseFormat);
|
||||
|
||||
// Common date formats to try parsing
|
||||
const DATE_FORMATS = [
|
||||
'YYYY-MM-DD HH:mm:ss',
|
||||
'YYYY-MM-DD HH:mm',
|
||||
'YYYY-MM-DD',
|
||||
'MM/DD/YYYY HH:mm:ss',
|
||||
'MM/DD/YYYY HH:mm',
|
||||
'MM/DD/YYYY',
|
||||
'DD/MM/YYYY HH:mm:ss',
|
||||
'DD/MM/YYYY HH:mm',
|
||||
'DD/MM/YYYY',
|
||||
'YYYY-MM-DDTHH:mm:ss.SSSZ', // ISO format
|
||||
'YYYY-MM-DDTHH:mm:ssZ',
|
||||
'YYYY-MM-DDTHH:mm:ss',
|
||||
'ddd MMM DD YYYY HH:mm:ss' // JavaScript date string format
|
||||
];
|
||||
|
||||
function parseDate(dateString: string): dayjs.Dayjs | null {
|
||||
const trimmedInput = dateString.trim();
|
||||
|
||||
if (!trimmedInput) {
|
||||
return null;
|
||||
}
|
||||
|
||||
// First try to parse as a timestamp (if it's all digits)
|
||||
if (/^\d+$/.test(trimmedInput)) {
|
||||
const timestamp = parseInt(trimmedInput, 10);
|
||||
// Check if it's a valid timestamp (reasonable range)
|
||||
if (timestamp > 0 && timestamp < 4102444800) {
|
||||
// Up to year 2100
|
||||
return dayjs.unix(timestamp);
|
||||
}
|
||||
}
|
||||
|
||||
// Try to parse with various formats
|
||||
for (const format of DATE_FORMATS) {
|
||||
const parsed = dayjs(trimmedInput, format, true);
|
||||
if (parsed.isValid()) {
|
||||
return parsed;
|
||||
}
|
||||
}
|
||||
|
||||
// Try default dayjs parsing as fallback
|
||||
const defaultParsed = dayjs(trimmedInput);
|
||||
if (defaultParsed.isValid()) {
|
||||
return defaultParsed;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
function convertSingleDateToEpoch(
|
||||
dateString: string,
|
||||
lineNumber: number
|
||||
): string {
|
||||
if (dateString.trim() === '') {
|
||||
return '';
|
||||
}
|
||||
|
||||
const parsedDate = parseDate(dateString);
|
||||
|
||||
if (!parsedDate) {
|
||||
throw new Error(
|
||||
`Invalid date format on line ${lineNumber}: "${dateString}"`
|
||||
);
|
||||
}
|
||||
|
||||
// Convert to UTC and get Unix timestamp
|
||||
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');
|
||||
|
||||
lines.forEach((line, index) => {
|
||||
const epoch = convertSingleDateToEpoch(line, index + 1);
|
||||
result.push(epoch);
|
||||
});
|
||||
|
||||
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');
|
||||
}
|
||||
3
src/pages/tools/time/convert-date-to-epoch/types.ts
Normal file
3
src/pages/tools/time/convert-date-to-epoch/types.ts
Normal file
|
|
@ -0,0 +1,3 @@
|
|||
export type InitialValuesType = {
|
||||
mode: 'dateToEpoch' | 'epochToDate';
|
||||
};
|
||||
|
|
@ -3,6 +3,7 @@ import { tool as daysDoHours } from './convert-days-to-hours/meta';
|
|||
import { tool as hoursToDays } from './convert-hours-to-days/meta';
|
||||
import { tool as convertSecondsToTime } from './convert-seconds-to-time/meta';
|
||||
import { tool as convertTimetoSeconds } from './convert-time-to-seconds/meta';
|
||||
import { tool as convertDateToEpoch } from './convert-date-to-epoch/meta';
|
||||
import { tool as truncateClockTime } from './truncate-clock-time/meta';
|
||||
|
||||
export const timeTools = [
|
||||
|
|
@ -10,6 +11,7 @@ export const timeTools = [
|
|||
hoursToDays,
|
||||
convertSecondsToTime,
|
||||
convertTimetoSeconds,
|
||||
convertDateToEpoch,
|
||||
truncateClockTime,
|
||||
timeBetweenDates
|
||||
];
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue