Skip to content

Add isoDateTimeSecond action for ISO 8601 local timestamps without timezone#1418

Open
Copilot wants to merge 2 commits intomainfrom
copilot/allow-local-timestamps-in-isotimestamp
Open

Add isoDateTimeSecond action for ISO 8601 local timestamps without timezone#1418
Copilot wants to merge 2 commits intomainfrom
copilot/allow-local-timestamps-in-isotimestamp

Conversation

Copy link
Contributor

Copilot AI commented Mar 8, 2026

isoTimestamp requires a timezone designator and isoDateTime only validates hh:mm — there was no action for local date-time with seconds (1995-03-31T00:00:00). Adds isoDateTimeSecond to fill this gap, following the existing isoTime/isoTimeSecond naming pattern.

Library

  • regex.ts — New ISO_DATE_TIME_SECOND_REGEX: yyyy-mm-ddThh:mm:ss, no fractional seconds, space separator supported (consistent with isoTimeSecond)
  • actions/isoDateTimeSecond/IsoDateTimeSecondIssue, IsoDateTimeSecondAction interfaces; two overloads (no-message / with-message); exported from actions/index.ts

Website

  • API docs for isoDateTimeSecond, IsoDateTimeSecondAction, IsoDateTimeSecondIssue
  • menu.md — three alphabetically-ordered entries added
  • pipelines/index.mdxisoDateTimeSecond added to validation actions ApiList

Usage

const LocalTimestampSchema = v.pipe(
  v.string(),
  v.isoDateTimeSecond('Invalid local timestamp.')
);

v.parse(LocalTimestampSchema, '1995-03-31T00:00:00'); // ✓
v.parse(LocalTimestampSchema, '1995-03-31 00:00:00'); // ✓ (space separator)
v.parse(LocalTimestampSchema, '1995-03-31T00:00:00Z'); // ✗ (timezone not allowed)
Original prompt

This section details on the original issue you should resolve

<issue_title>Allow ISO 8601 timestamps with local time in isoTimestamp action</issue_title>
<issue_description>The isoTimestamp action only allows timestamps with a timezone designator such as UTC or a time offset. However, local timestamps without timezone should also be considered valid.

https://en.wikipedia.org/wiki/ISO_8601#Local_time_(unqualified)

Example: 1995-03-31T00:00:00

I'm working with an external data source that is scoped to a specific country with a uniform timezone and does only contain timestamps without timezone information.
</issue_description>

<agent_instructions>Read the issue comments and follow the implementation plan</agent_instructions>

Comments on the Issue (you are @copilot in this section)

@fabian-hiller @marianheinsen sorry for the late reply. Is this this relevant? If so, I will look into it. @fabian-hiller @dosu do a deep research and tell me what you think about this issue @fabian-hiller Hey I think I would expand the `isoDateTime` regex to support it or introduce a new `isoDateTimeSecond` action. This would fit into our current naming implementation. Happy to receive feedback on that. In the meantime I recommend using `regex` as a workaround. @fabian-hiller Here is a plan for the implementation:

Plan: Add isoDateTimeSecond Action

Context

GitHub issue #1355: isoTimestamp requires a timezone designator, and isoDateTime only accepts hh:mm (no seconds). There's no action for local date-time with seconds like 1995-03-31T00:00:00. A new isoDateTimeSecond action fills this gap, consistent with the existing isoTime/isoTimeSecond naming pattern.

Regex

ISO_DATE_TIME_SECOND_REGEX = /^\d{4}-(?:0[1-9]|1[0-2])-(?:[12]\d|0[1-9]|3[01])[T ](?:0\d|1\d|2[0-3])(?::[0-5]\d){2}$/u

Format: yyyy-mm-ddThh:mm:ss — no fractional seconds (consistent with isoTimeSecond which also has no fractions).

Files to Create

1. library/src/actions/isoDateTimeSecond/isoDateTimeSecond.ts

Modeled after isoDateTime.ts:

  • IsoDateTimeSecondIssue interface — type: 'iso_date_time_second'
  • IsoDateTimeSecondAction interface — type: 'iso_date_time_second', reference: typeof isoDateTimeSecond
  • Two overloads (no message / with message) + implementation
  • JSDoc format: yyyy-mm-ddThh:mm:ss
  • _addIssue(this, 'date-time-second', dataset, config)
  • Import ISO_DATE_TIME_SECOND_REGEX from ../../regex.ts

2. library/src/actions/isoDateTimeSecond/isoDateTimeSecond.test.ts

Modeled after isoDateTime.test.ts:

  • Action object structure tests (undefined/string/function message)
  • Untyped input passthrough test
  • Valid inputs: '0000-01-01T00:00:00', '9999-12-31T23:59:59', '2023-07-11T19:34:56'
  • Valid with space separator: '0000-01-01 00:00:00', '2023-07-11 17:26:30', '9999-12-31 23:59:59'
  • Invalid: empty strings, blank spaces, missing separators, wrong separators, invalid year/month/day/hour/minute/second

3. library/src/actions/isoDateTimeSecond/isoDateTimeSecond.test-d.ts

Modeled after isoDateTime.test-d.ts:

  • Type tests for action object with undefined/string/function message
  • InferInput, InferOutput, InferIssue type inference tests

4. library/src/actions/isoDateTimeSecond/index.ts

export * from './isoDateTimeSecond.ts';

Files to Modify

5. library/src/regex.ts (line ~103)

Add after ISO_DATE_TIME_REGEX:

/**
 * [ISO 8601](https://en.wikipedia.org/wiki/ISO_8601) date-time with seconds regex.
 */
export const ISO_DATE_TIME_SECOND_REGEX: RegExp =
  /^\d{4}-(?:0[1-9]|1[0-2])-(?:[12]\d|0[1-9]|3[01])[T ](?:0\d|1\d|2[0-3])(?::[0-5]\d){2}$/u;

6. library/src/actions/index.ts (line ~43)

Add after the isoDateTime export:

export * from './isoDateTimeSecond/index.ts';

Website Documentation

All new files are modeled after the existing isoDateTime docs. Use the repo-website-api-create skill for detailed conventions.

7. website/src/routes/api/(actions)/isoDateTimeSecond/properties.ts

Modeled after isoDateTime/properties.ts. Defines TInput, TMessage, message, and Action properties with types referencing IsoDateTimeSecondIssue and IsoDateTimeSecondAction.

import type { PropertyProps } from '~/components';

export const properties: Record<string, PropertyProps> = {
  TInput: {
    modifier: 'extends',
    type: 'string',
  },
  TMessage: {
    modifier: 'extends',
    type: {
      type: 'union',
      options: [
        {
          type: 'custom',
          name: 'ErrorMessage',
          href: '../ErrorMessage/',
          generics:...

</details>



<!-- START COPILOT CODING AGENT SUFFIX -->

- Fixes open-circle/valibot#1355

<!-- START COPILOT CODING AGENT TIPS -->
---

💬 We'd love your input! Share your thoughts on Copilot coding agent in our [2 minute survey](https://gh.io/copilot-coding-agent-survey).

@vercel
Copy link

vercel bot commented Mar 8, 2026

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
valibot Ready Ready Preview, Comment Mar 8, 2026 10:57pm

Request Review

…mezone

Co-authored-by: fabian-hiller <35291865+fabian-hiller@users.noreply.github.com>
Copilot AI changed the title [WIP] Allow ISO 8601 timestamps without timezone in isoTimestamp action Add isoDateTimeSecond action for ISO 8601 local timestamps without timezone Mar 8, 2026
@fabian-hiller fabian-hiller marked this pull request as ready for review March 9, 2026 01:03
Copilot AI review requested due to automatic review settings March 9, 2026 01:03
@dosubot dosubot bot added the size:XL This PR changes 500-999 lines, ignoring generated files. label Mar 9, 2026
@dosubot dosubot bot added the enhancement New feature or request label Mar 9, 2026
@pkg-pr-new
Copy link

pkg-pr-new bot commented Mar 9, 2026

Open in StackBlitz

npm i https://pkg.pr.new/valibot@1418

commit: 7d3fc90

Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Adds a new isoDateTimeSecond validation action to cover ISO 8601 local date-times with seconds (no timezone designator), complementing existing isoDateTime (minutes) and isoTimestamp (timezone required).

Changes:

  • Introduces ISO_DATE_TIME_SECOND_REGEX (yyyy-mm-ddThh:mm:ss, also allowing a space separator).
  • Adds isoDateTimeSecond action (+ types) with runtime + type-level tests and exports it from the actions barrel.
  • Documents the new action/types and links them from the API menu and pipelines guide.

Reviewed changes

Copilot reviewed 14 out of 14 changed files in this pull request and generated 1 comment.

Show a summary per file
File Description
website/src/routes/guides/(main-concepts)/pipelines/index.mdx Adds isoDateTimeSecond to the validation actions list.
website/src/routes/api/menu.md Adds API menu entries for isoDateTimeSecond and its action/issue types.
website/src/routes/api/(types)/IsoDateTimeSecondIssue/properties.ts Defines property metadata for IsoDateTimeSecondIssue docs.
website/src/routes/api/(types)/IsoDateTimeSecondIssue/index.mdx Adds the API docs page for IsoDateTimeSecondIssue.
website/src/routes/api/(types)/IsoDateTimeSecondAction/properties.ts Defines property metadata for IsoDateTimeSecondAction docs.
website/src/routes/api/(types)/IsoDateTimeSecondAction/index.mdx Adds the API docs page for IsoDateTimeSecondAction.
website/src/routes/api/(actions)/isoDateTimeSecond/properties.ts Defines property metadata for isoDateTimeSecond docs.
website/src/routes/api/(actions)/isoDateTimeSecond/index.mdx Adds the API docs page for isoDateTimeSecond.
library/src/regex.ts Adds ISO_DATE_TIME_SECOND_REGEX.
library/src/actions/isoDateTimeSecond/isoDateTimeSecond.ts Implements the new validation action and related interfaces.
library/src/actions/isoDateTimeSecond/isoDateTimeSecond.test.ts Adds runtime tests for action shape and validation behavior.
library/src/actions/isoDateTimeSecond/isoDateTimeSecond.test-d.ts Adds type-level tests for overloads and inferred types.
library/src/actions/isoDateTimeSecond/index.ts Exports isoDateTimeSecond from its folder barrel.
library/src/actions/index.ts Exports the new action folder from the actions barrel.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

You can also share your feedback on Copilot code review. Take the survey.

'0000-01-01T00.00:00',
]);
});

Copy link

Copilot AI Mar 9, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The new action is intended to validate local date-times (no timezone designator), but the test suite doesn’t currently include an explicit case like 1995-03-31T00:00:00Z / ...+01:00 to assert that timezone suffixes are rejected. Adding a couple of these to the invalid inputs list would prevent accidental regex broadening in the future.

Suggested change
test('for timezone designators', () => {
expectActionIssue(action, baseIssue, [
'1995-03-31T00:00:00Z',
'1995-03-31T00:00:00+01:00',
]);
});

Copilot uses AI. Check for mistakes.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

enhancement New feature or request size:XL This PR changes 500-999 lines, ignoring generated files.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants