import { describe, it, expect } from 'vitest' import { parseTimestampInput, formatTimestampMs, parseDateString, dateToTimestamp, } from '../../src/utils/timestamp.js' describe('timestamp', () => { // 2024-01-15 12:30:45 UTC+8 depends on local TZ - use fixed ms const knownMs = 1705299045123 describe('parseTimestampInput', () => { it('returns empty error for blank input', () => { expect(parseTimestampInput('', 'seconds')).toEqual({ error: 'empty' }) }) it('parses seconds timestamp (10 digits)', () => { const seconds = Math.floor(knownMs / 1000) const result = parseTimestampInput(String(seconds), 'seconds') expect(result.timestampMs).toBe(seconds * 1000) }) it('parses milliseconds timestamp', () => { const result = parseTimestampInput(String(knownMs), 'milliseconds') expect(result.timestampMs).toBe(knownMs) }) it('parses 13-digit value as milliseconds even in seconds mode', () => { const result = parseTimestampInput(String(knownMs), 'seconds') expect(result.timestampMs).toBe(knownMs) }) it('parses nanoseconds timestamp', () => { const ns = BigInt(knownMs) * BigInt(1000000) + BigInt(456789) const result = parseTimestampInput(String(ns), 'nanoseconds') expect(result.timestampMs).toBe(knownMs) expect(result.nanoseconds).toBe(456789) }) it('returns error for invalid number', () => { expect(parseTimestampInput('abc', 'seconds')).toEqual({ error: 'invalid_number' }) }) it('returns error for invalid nanoseconds', () => { expect(parseTimestampInput('not-a-bigint', 'nanoseconds')).toEqual({ error: 'invalid_nanoseconds' }) }) }) describe('formatTimestampMs', () => { it('formats seconds precision without milliseconds', () => { const result = formatTimestampMs(knownMs, 'seconds') expect(result.value).toMatch(/^\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}$/) expect(result.value).not.toContain('.') }) it('formats milliseconds precision', () => { const result = formatTimestampMs(knownMs, 'milliseconds') expect(result.value).toMatch(/^\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}\.\d{3}$/) }) it('formats nanoseconds precision with extra digits', () => { const result = formatTimestampMs(knownMs, 'nanoseconds', 123456) expect(result.value).toMatch(/\.\d{9}$/) }) it('returns error for invalid date', () => { expect(formatTimestampMs(NaN, 'seconds')).toEqual({ error: 'invalid_date' }) }) }) describe('parseDateString', () => { it('returns empty error for blank', () => { expect(parseDateString('')).toEqual({ error: 'empty' }) }) it('parses standard datetime format', () => { const result = parseDateString('2024-06-15 10:30:00') expect(result.date).toBeInstanceOf(Date) expect(result.date.getFullYear()).toBe(2024) }) it('parses datetime with milliseconds', () => { const result = parseDateString('2024-06-15 10:30:00.123') expect(result.date).toBeInstanceOf(Date) }) it('returns error for invalid date string', () => { expect(parseDateString('not-a-date')).toEqual({ error: 'invalid_date' }) }) }) describe('dateToTimestamp', () => { const date = new Date(2024, 5, 15, 10, 30, 0) it('converts to seconds', () => { const result = dateToTimestamp(date, 'seconds') expect(parseInt(result.value, 10)).toBe(Math.floor(date.getTime() / 1000)) }) it('converts to milliseconds', () => { const result = dateToTimestamp(date, 'milliseconds') expect(result.value).toBe(String(date.getTime())) }) it('converts to nanoseconds', () => { const result = dateToTimestamp(date, 'nanoseconds') expect(result.value).toBe(String(BigInt(date.getTime()) * BigInt(1000000))) }) }) })