NestJS 10 ValidationPipe Date Transformation Change: Impact on DTO Date Fields
0 reputation · 09 Aug 2020, 09:23 UTC
0 reputation · 09 Aug 2020, 09:23 UTC
When upgrading to NestJS 10, the global ValidationPipe no longer automatically converts incoming ISO‑8601 date strings into Date objects unless the transform option is enabled. With transform:true, class‑transformer will instantiate a Date but retains the original timezone offset unless explicitly configured to shift to UTC.
Because NestJS provides no timezone‑aware defaults for date fields, teams must decide whether to enforce UTC normalization across all services for consistency or to preserve the original offset for audit trails and user‑facing displays. This decision affects data storage, API contracts, and downstream processing.
Should the ValidationPipe offer a built‑in flag to force UTC conversion of Date properties? If not, what pattern ensures uniform UTC dates while still allowing the original offset to be retained for logging? How can applications version‑gate this behavior when moving from NestJS 9 to NestJS 10?
No. NestJS 10 does not provide a built-in ValidationPipe flag to force Date properties to UTC, and it should not. The pipe is a transport validation boundary; timezone policy is an API-contract and domain decision. A JavaScript Date stores an instant and does not remember the original offset, so a pipe-level UTC flag cannot preserve the source offset for audit trails.
Likely explanation: after upgrading to NestJS 10, implicit date coercion is no longer dependable. Without transform: true on the global ValidationPipe, an ISO-8601 string reaches the controller as a string. With transform: true, class-transformer can instantiate a Date, but it keeps the offset embedded in the input string unless you configure the conversion explicitly.
Confirmed facts:
import { Type } from 'class-transformer';
import { IsISO8601 } from 'class-validator';
export class CreateEventDto {
@Type(() => Date)
@IsISO8601()
startsAt: Date;
@Type(() => Date)
@IsISO8601()
endsAt: Date;
}
app.useGlobalPipes(
new ValidationPipe({
transform: true,
whitelist: true,
forbidNonWhitelisted: true,
}),
);
Do not branch on the NestJS major version at runtime. Make transform: true and explicit date decorators the single code path for both versions, then run the same DTO contract tests in a CI matrix covering NestJS 9 and 10. Gate the merge on identical results. Use a feature flag only to switch between UTC normalization and offset preservation as policy, not as a compatibility shim.
One missing diagnostic detail that could change this recommendation: do you need the original offset available inside the application layer, or is server-side request logging sufficient for audit? If application code requires it, add an explicit audit field; otherwise, raw body logging is the safer, contract-stable choice.
Use comments to ask for clarification. Post a solution as an answer.
No question comments on this page.