Skip to content

Commit 51433f0

Browse files
wing328b2lclaudemacjohnny
authored
[typescript-fetch] centralise date handling, add dateLibrary (#24722)
* [typescript-fetch] centralise date handling, add dateLibrary, fix format: date Date handling was spread across four templates, each inlining its own expression. That had three consequences: 1. `format: date` was not handled at all for form parameters, so a Date was appended raw and stringified by the browser ("Wed Aug 05 2026 00:00:00 GMT+0200 (…)") instead of "2026-08-05". 2. `format: date` shifted by a day everywhere except UTC, in one direction or the other. Parsing (`new Date('2026-08-05')`) and serialising (`.toISOString().substring(0, 10)`) both work in UTC, but consumers do not: a date picker builds local midnight and display reads local getters. West of UTC a date from the API displays as the previous day; east of UTC a locally built date is sent as the previous day. An RFC 3339 full-date has no offset, so both ends have to use the same wall clock — they now both use the local calendar. `format: date-time` is a genuine instant and stays UTC. 3. Whether dates were represented as Date or string was decided by `withoutRuntimeChecks`, an unrelated flag about payload validation. All call sites (models, oneOf models, path/query/form parameters and the querystring helper) now route through serializeDate/serializeDateTime and parseDate/parseDateTime in runtime.ts, so the representation is defined in one place. The new `dateLibrary` option (`date`, the default and previous behaviour, or `string`) makes the choice explicit; `withoutRuntimeChecks` implies `string`, as before, since there is no model code left to convert with. Adds a spec fixture covering every location a date can appear in, two sample builds (one per option value), and tests for the option, the fallback and the serialisation semantics. * [typescript-fetch] address review: ES6 target, year 0-99, invalid dates, unused imports - serializeDate no longer uses padStart, which is ES2017: the es6-target sample did not compile against its own tsconfig. - parseDate builds the local date with setFullYear, so years 0000-0099 keep their century instead of picking up the multi-argument Date constructor's 1900 offset ("0045-08-05" was parsed as 1945). - parseDate rejects components that roll over, so an out-of-range date or a day the local zone skipped returns Invalid Date rather than a plausible wrong one. Previously "2026-13-45" became 2027-02-14. - serializeDate throws RangeError on an invalid Date instead of emitting "0NaN-NaN-NaN", matching serializeDateTime. - Models without a date property no longer import the date helpers, via a new x-hasDateVars extension mirroring the template's own branches. This reverts most of the sample churn from the previous commit. Drops testDateFormatUsesTheLocalCalendar: runtime.ts is identical for every spec, so asserting its body only restated the template. The per-build tsconfig typecheck covers the ES6 regression properly. * [typescript-fetch] align the oneOf date guards with the date helpers The oneOf branches tested a value with `new Date(json)` but converted it with parseDate, so the two could disagree: "2026-02-30" passes the lenient test (V8 rolls it to March 2) and then parseDate rejects it, leaving the branch selected and returning Invalid Date. Testing with the same helper that does the conversion lets the oneOf fall through to another branch instead. Adds a oneOf date member to the date-handling fixture. No sample in the repo exercised these branches, so the generated form of the guard was invisible in the samples; only the scalar variant is left out, because a scalar oneOf primitive already fails `tsc --strict` on master (it can return undefined, which is not in the union). Drops the comment justifying the ES6-safe padding: the per-build tsconfig typecheck already fails if someone reaches for padStart again. * [typescript-fetch] rebase on master: fold the #24509 null guards into the date helpers Upstream #24509 null-guarded required date properties; keep that guard but route the conversion through parseDate/serializeDate. Port the form param date handling into the apisFormParams partial extracted by #23935, and regenerate the affected samples. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> * Update modules/openapi-generator/src/main/resources/typescript-fetch/runtime.mustache Co-authored-by: Esteban Gehring <esteban.gehring@gmail.com> * update TS samples --------- Co-authored-by: Nicolas Medda <nicolas@lecomptoirdespharmacies.fr> Co-authored-by: Claude Fable 5 <noreply@anthropic.com> Co-authored-by: Nicolas Medda <b2l.powa@gmail.com> Co-authored-by: Esteban Gehring <esteban.gehring@gmail.com>
1 parent dbf38dc commit 51433f0

94 files changed

Lines changed: 3832 additions & 134 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
generatorName: typescript-fetch
2+
outputDir: samples/client/petstore/typescript-fetch/builds/date-library-date
3+
inputSpec: modules/openapi-generator/src/test/resources/3_0/typescript-fetch/date-handling.yaml
4+
templateDir: modules/openapi-generator/src/main/resources/typescript-fetch
5+
additionalProperties:
6+
dateLibrary: date
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
generatorName: typescript-fetch
2+
outputDir: samples/client/petstore/typescript-fetch/builds/date-library-string
3+
inputSpec: modules/openapi-generator/src/test/resources/3_0/typescript-fetch/date-handling.yaml
4+
templateDir: modules/openapi-generator/src/main/resources/typescript-fetch
5+
additionalProperties:
6+
dateLibrary: string

docs/generators/typescript-fetch.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ These options may be applied as additional-properties (cli) or configOptions (pl
1919
| Option | Description | Values | Default |
2020
| ------ | ----------- | ------ | ------- |
2121
|allowUnicodeIdentifiers|boolean, toggles whether unicode identifiers are allowed in names or not, default is false| |false|
22+
|dateLibrary|Option. Date library to use.|<dl><dt>**date**</dt><dd>Native Date. `format: date` and `format: date-time` are both mapped to Date and (de)serialized by the runtime.</dd><dt>**string**</dt><dd>Plain string. Values are passed through untouched, leaving date handling to the consumer.</dd></dl>|date|
2223
|disallowAdditionalPropertiesIfNotPresent|If false, the 'additionalProperties' implementation (set to true by default) is compliant with the OAS and JSON schema specifications. If true (default), keep the old (incorrect) behaviour that 'additionalProperties' is set to false by default.|<dl><dt>**false**</dt><dd>The 'additionalProperties' implementation is compliant with the OAS and JSON schema specifications.</dd><dt>**true**</dt><dd>Keep the old (incorrect) behaviour that 'additionalProperties' is set to false by default.</dd></dl>|true|
2324
|ensureUniqueParams|Whether to ensure parameter names are unique in an operation (rename parameters that are not).| |true|
2425
|enumNameSuffix|Suffix that will be appended to all enum names.| |Enum|

modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/TypeScriptFetchClientCodegen.java

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,10 @@ public class TypeScriptFetchClientCodegen extends AbstractTypeScriptClientCodege
6363
public static final String USE_SINGLE_REQUEST_PARAMETER = "useSingleRequestParameter";
6464
public static final String PREFIX_PARAMETER_INTERFACES = "prefixParameterInterfaces";
6565
public static final String WITHOUT_RUNTIME_CHECKS = "withoutRuntimeChecks";
66+
public static final String DATE_LIBRARY = "dateLibrary";
67+
public static final String DATE_LIBRARY_DESC = "Option. Date library to use.";
68+
public static final String DATE_LIBRARY_DATE = "date";
69+
public static final String DATE_LIBRARY_STRING = "string";
6670
public static final String STRING_ENUMS = "stringEnums";
6771
public static final String STRING_ENUMS_DESC = "Generate string enums instead of objects for enum values.";
6872
public static final String IMPORT_FILE_EXTENSION_SWITCH = "importFileExtension";
@@ -85,6 +89,7 @@ public class TypeScriptFetchClientCodegen extends AbstractTypeScriptClientCodege
8589
protected boolean addedApiIndex = false;
8690
protected boolean addedModelIndex = false;
8791
protected boolean withoutRuntimeChecks = false;
92+
protected String dateLibrary = DATE_LIBRARY_DATE;
8893
protected boolean stringEnums = false;
8994
protected String fileNaming = PASCAL_CASE;
9095
protected String apiDocPath = "docs";
@@ -102,6 +107,7 @@ public class TypeScriptFetchClientCodegen extends AbstractTypeScriptClientCodege
102107
private static final String X_OPERATION_RETURN_PASSTHROUGH = "x-operationReturnPassthrough";
103108
private static final String X_KEEP_AS_JS_OBJECT = "x-keepAsJSObject";
104109
private static final String X_TYPESCRIPT_FETCH_API_EXAMPLE = "x-typescriptFetchApiExample";
110+
private static final String X_HAS_DATE_VARS = "x-hasDateVars";
105111
private static final String BLOB_API_EXAMPLE = "new Blob(['example file content'], { type: 'application/octet-stream' })";
106112

107113
protected boolean sagasAndRecords = false;
@@ -140,6 +146,13 @@ public TypeScriptFetchClientCodegen() {
140146
this.cliOptions.add(new CliOption(CodegenConstants.USE_SINGLE_REQUEST_PARAMETER, CodegenConstants.USE_SINGLE_REQUEST_PARAMETER_DESC, SchemaTypeUtil.BOOLEAN_TYPE).defaultValue(Boolean.TRUE.toString()));
141147
this.cliOptions.add(new CliOption(PREFIX_PARAMETER_INTERFACES, "Setting this property to true will generate parameter interface declarations prefixed with API class name to avoid name conflicts.", SchemaTypeUtil.BOOLEAN_TYPE).defaultValue(Boolean.FALSE.toString()));
142148
this.cliOptions.add(new CliOption(WITHOUT_RUNTIME_CHECKS, "Setting this property to true will remove any runtime checks on the request and response payloads. Payloads will be casted to their expected types.", SchemaTypeUtil.BOOLEAN_TYPE).defaultValue(Boolean.FALSE.toString()));
149+
150+
CliOption dateLibraryOption = new CliOption(DATE_LIBRARY, DATE_LIBRARY_DESC).defaultValue(this.getDateLibrary());
151+
Map<String, String> dateOptions = new HashMap<>();
152+
dateOptions.put(DATE_LIBRARY_DATE, "Native Date. `format: date` and `format: date-time` are both mapped to Date and (de)serialized by the runtime.");
153+
dateOptions.put(DATE_LIBRARY_STRING, "Plain string. Values are passed through untouched, leaving date handling to the consumer.");
154+
dateLibraryOption.setEnum(dateOptions);
155+
this.cliOptions.add(dateLibraryOption);
143156
this.cliOptions.add(new CliOption(SAGAS_AND_RECORDS, "Setting this property to true will generate additional files for use with redux-saga and immutablejs.", SchemaTypeUtil.BOOLEAN_TYPE).defaultValue(Boolean.FALSE.toString()));
144157
this.cliOptions.add(new CliOption(STRING_ENUMS, STRING_ENUMS_DESC, SchemaTypeUtil.BOOLEAN_TYPE).defaultValue(Boolean.FALSE.toString()));
145158
this.cliOptions.add(new CliOption(IMPORT_FILE_EXTENSION_SWITCH, IMPORT_FILE_EXTENSION_SWITCH_DESC).defaultValue(""));
@@ -198,6 +211,14 @@ public void setWithoutRuntimeChecks(Boolean withoutRuntimeChecks) {
198211
this.withoutRuntimeChecks = withoutRuntimeChecks;
199212
}
200213

214+
public String getDateLibrary() {
215+
return this.dateLibrary;
216+
}
217+
218+
public void setDateLibrary(String dateLibrary) {
219+
this.dateLibrary = dateLibrary;
220+
}
221+
201222
public Boolean getStringEnums() {
202223
return this.stringEnums;
203224
}
@@ -315,11 +336,34 @@ public void processOpts() {
315336
this.setFileNaming(additionalProperties.get(FILE_NAMING).toString());
316337
}
317338

339+
if (additionalProperties.containsKey(DATE_LIBRARY)) {
340+
this.setDateLibrary(additionalProperties.get(DATE_LIBRARY).toString());
341+
}
342+
318343
if (!withoutRuntimeChecks) {
319344
this.modelTemplateFiles.put("models.mustache", ".ts");
345+
}
346+
347+
// `date` needs the model (de)serialization to convert with, which
348+
// withoutRuntimeChecks removes: the raw string would just be cast to Date.
349+
if (withoutRuntimeChecks && DATE_LIBRARY_DATE.equals(this.dateLibrary)) {
350+
if (additionalProperties.containsKey(DATE_LIBRARY)) {
351+
LOGGER.warn("{}={} is not compatible with {}=true; falling back to {}={}.",
352+
DATE_LIBRARY, DATE_LIBRARY_DATE, WITHOUT_RUNTIME_CHECKS, DATE_LIBRARY, DATE_LIBRARY_STRING);
353+
}
354+
this.dateLibrary = DATE_LIBRARY_STRING;
355+
}
356+
357+
if (DATE_LIBRARY_DATE.equals(this.dateLibrary)) {
320358
typeMapping.put("date", "Date");
321359
typeMapping.put("DateTime", "Date");
360+
} else {
361+
typeMapping.put("date", "string");
362+
typeMapping.put("DateTime", "string");
322363
}
364+
additionalProperties.put(DATE_LIBRARY, this.dateLibrary);
365+
// Mustache cannot compare strings, so expose the selected library as a flag.
366+
additionalProperties.put("isDateLibraryDate", DATE_LIBRARY_DATE.equals(this.dateLibrary));
323367

324368
if (additionalProperties.containsKey(SAGAS_AND_RECORDS)) {
325369
this.setSagasAndRecords(convertPropertyToBoolean(SAGAS_AND_RECORDS));
@@ -419,6 +463,12 @@ public ModelsMap postProcessModels(ModelsMap objs) {
419463
ExtendedCodegenModel cm = (ExtendedCodegenModel) mo.getModel();
420464
cm.imports = new TreeSet<>(cm.imports);
421465
this.processCodeGenModel(cm);
466+
// Mirrors the branches in modelGeneric.mustache that call the date helpers, so a
467+
// model without dates does not import them.
468+
cm.vendorExtensions.put(X_HAS_DATE_VARS, cm.vars.stream()
469+
.filter(ExtendedCodegenProperty.class::isInstance)
470+
.map(ExtendedCodegenProperty.class::cast)
471+
.anyMatch(v -> v.isPrimitiveType && !v.isArray && (v.isDateType() || v.isDateTimeType())));
422472
}
423473

424474
// Add supporting file only if we plan to generate files in /models

modules/openapi-generator/src/main/resources/typescript-fetch/apis.mustache

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -308,15 +308,15 @@ export class {{classname}} extends runtime.BaseAPI {
308308
{{#pathParams}}
309309
{{#isDateTimeType}}
310310
if (requestParameters['{{paramName}}'] instanceof Date) {
311-
urlPath = urlPath.replace({{=<< >>=}}'{<<baseName>>}'<<={{ }}=>>, encodeURIComponent(requestParameters['{{paramName}}'].toISOString()));
311+
urlPath = urlPath.replace({{=<< >>=}}'{<<baseName>>}'<<={{ }}=>>, encodeURIComponent(runtime.serializeDateTime(requestParameters['{{paramName}}'])));
312312
} else {
313313
urlPath = urlPath.replace({{=<< >>=}}'{<<baseName>>}'<<={{ }}=>>, encodeURIComponent(String(requestParameters['{{paramName}}'])));
314314
}
315315
{{/isDateTimeType}}
316316
{{^isDateTimeType}}
317317
{{#isDateType}}
318318
if (requestParameters['{{paramName}}'] instanceof Date) {
319-
urlPath = urlPath.replace({{=<< >>=}}'{<<baseName>>}'<<={{ }}=>>, encodeURIComponent(requestParameters['{{paramName}}'].toISOString().substring(0,10)));
319+
urlPath = urlPath.replace({{=<< >>=}}'{<<baseName>>}'<<={{ }}=>>, encodeURIComponent(runtime.serializeDate(requestParameters['{{paramName}}'])));
320320
} else {
321321
urlPath = urlPath.replace({{=<< >>=}}'{<<baseName>>}'<<={{ }}=>>, encodeURIComponent(String(requestParameters['{{paramName}}'])));
322322
}

modules/openapi-generator/src/main/resources/typescript-fetch/apisAssignQueryParam.mustache

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
11
{{! Assign query parameters based on their type }}
22
{{#isDateTimeType}}
3-
queryParameters['{{baseName}}'] = (requestParameters['{{paramName}}'] as any).toISOString();
3+
queryParameters['{{baseName}}'] = runtime.serializeDateTime(requestParameters['{{paramName}}'] as any);
44
{{/isDateTimeType}}
55
{{^isDateTimeType}}
66
{{#isDateType}}
7-
queryParameters['{{baseName}}'] = (requestParameters['{{paramName}}'] as any).toISOString().substring(0,10);
7+
queryParameters['{{baseName}}'] = runtime.serializeDate(requestParameters['{{paramName}}'] as any);
88
{{/isDateType}}
99
{{^isDateType}}
1010
queryParameters['{{baseName}}'] = requestParameters['{{paramName}}'];

modules/openapi-generator/src/main/resources/typescript-fetch/apisFormParams.mustache

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,9 +37,13 @@
3737
{{^isArray}}
3838
if (requestParameters['{{paramName}}'] != null) {
3939
{{#isDateTimeType}}
40-
formParams.append('{{baseName}}', (requestParameters['{{paramName}}'] as any).toISOString());
40+
formParams.append('{{baseName}}', runtime.serializeDateTime(requestParameters['{{paramName}}'] as any));
4141
{{/isDateTimeType}}
4242
{{^isDateTimeType}}
43+
{{#isDateType}}
44+
formParams.append('{{baseName}}', runtime.serializeDate(requestParameters['{{paramName}}'] as any));
45+
{{/isDateType}}
46+
{{^isDateType}}
4347
{{#isPrimitiveType}}
4448
formParams.append('{{baseName}}', requestParameters['{{paramName}}'] as any);
4549
{{/isPrimitiveType}}
@@ -60,6 +64,7 @@
6064
{{/withoutRuntimeChecks}}
6165
{{/isEnumRef}}
6266
{{/isPrimitiveType}}
67+
{{/isDateType}}
6368
{{/isDateTimeType}}
6469
}
6570

modules/openapi-generator/src/main/resources/typescript-fetch/modelGeneric.mustache

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { mapValues } from '../runtime{{importFileExtension}}';
1+
import { mapValues{{#isDateLibraryDate}}{{#vendorExtensions.x-hasDateVars}}, parseDate, parseDateTime, serializeDate, serializeDateTime{{/vendorExtensions.x-hasDateVars}}{{/isDateLibraryDate}} } from '../runtime{{importFileExtension}}';
22
{{#hasImports}}
33
{{#tsImports}}
44
import type { {{{classname}}} } from './{{filename}}{{importFileExtension}}';
@@ -98,10 +98,10 @@ export function {{classname}}FromJSONTyped(json: any, ignoreDiscriminator: boole
9898
{{/isArray}}
9999
{{^isArray}}
100100
{{#isDateType}}
101-
'{{name}}': {{^required}}{{#isNullable}}json['{{baseName}}'] === undefined ? undefined : json['{{baseName}}'] === null ? null : {{/isNullable}}{{^isNullable}}json['{{baseName}}'] == null ? undefined : {{/isNullable}}{{/required}}({{#required}}{{#isNullable}}json['{{baseName}}'] == null ? null : {{/isNullable}}{{^isNullable}}json['{{baseName}}'] == null ? json['{{baseName}}'] : {{/isNullable}}{{/required}}new Date(json['{{baseName}}'])),
101+
'{{name}}': {{^required}}{{#isNullable}}json['{{baseName}}'] === undefined ? undefined : json['{{baseName}}'] === null ? null : {{/isNullable}}{{^isNullable}}json['{{baseName}}'] == null ? undefined : {{/isNullable}}{{/required}}({{#required}}{{#isNullable}}json['{{baseName}}'] == null ? null : {{/isNullable}}{{^isNullable}}json['{{baseName}}'] == null ? json['{{baseName}}'] : {{/isNullable}}{{/required}}parseDate(json['{{baseName}}'])),
102102
{{/isDateType}}
103103
{{#isDateTimeType}}
104-
'{{name}}': {{^required}}{{#isNullable}}json['{{baseName}}'] === undefined ? undefined : json['{{baseName}}'] === null ? null : {{/isNullable}}{{^isNullable}}json['{{baseName}}'] == null ? undefined : {{/isNullable}}{{/required}}({{#required}}{{#isNullable}}json['{{baseName}}'] == null ? null : {{/isNullable}}{{^isNullable}}json['{{baseName}}'] == null ? json['{{baseName}}'] : {{/isNullable}}{{/required}}new Date(json['{{baseName}}'])),
104+
'{{name}}': {{^required}}{{#isNullable}}json['{{baseName}}'] === undefined ? undefined : json['{{baseName}}'] === null ? null : {{/isNullable}}{{^isNullable}}json['{{baseName}}'] == null ? undefined : {{/isNullable}}{{/required}}({{#required}}{{#isNullable}}json['{{baseName}}'] == null ? null : {{/isNullable}}{{^isNullable}}json['{{baseName}}'] == null ? json['{{baseName}}'] : {{/isNullable}}{{/required}}parseDateTime(json['{{baseName}}'])),
105105
{{/isDateTimeType}}
106106
{{^isDateType}}
107107
{{^isDateTimeType}}
@@ -173,10 +173,10 @@ export function {{classname}}ToJSONTyped(value?: {{#hasReadOnly}}Omit<{{classnam
173173
{{^isReadOnly}}
174174
{{#isPrimitiveType}}
175175
{{#isDateType}}
176-
'{{baseName}}': value['{{name}}'] == null ? value['{{name}}'] : value['{{name}}'].toISOString().substring(0,10),
176+
'{{baseName}}': value['{{name}}'] == null ? value['{{name}}'] : serializeDate(value['{{name}}']),
177177
{{/isDateType}}
178178
{{#isDateTimeType}}
179-
'{{baseName}}': value['{{name}}'] == null ? value['{{name}}'] : value['{{name}}'].toISOString(),
179+
'{{baseName}}': value['{{name}}'] == null ? value['{{name}}'] : serializeDateTime(value['{{name}}']),
180180
{{/isDateTimeType}}
181181
{{#isArray}}
182182
'{{baseName}}': {{#uniqueItems}}{{^required}}value['{{name}}'] == null ? undefined : {{/required}}{{#required}}{{#isNullable}}value['{{name}}'] == null ? null : {{/isNullable}}{{/required}}Array.from(value['{{name}}'] as Set<any>){{/uniqueItems}}{{^uniqueItems}}value['{{name}}']{{/uniqueItems}},

modules/openapi-generator/src/main/resources/typescript-fetch/modelOneOf.mustache

Lines changed: 15 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,6 @@
1+
{{#isDateLibraryDate}}
2+
import { parseDate, parseDateTime, serializeDate, serializeDateTime } from '../runtime{{importFileExtension}}';
3+
{{/isDateLibraryDate}}
14
{{#hasImports}}
25
{{#oneOfArrays}}
36
import type { {{{.}}} } from './{{.}}{{importFileExtension}}';
@@ -69,15 +72,15 @@ export function {{classname}}FromJSONTyped(json: any, ignoreDiscriminator: boole
6972
{{#items}}
7073
{{#isDateType}}
7174
if (Array.isArray(json)) {
72-
if (json.every(item => !(isNaN(new Date(item).getTime())))) {
73-
return json.map(value => new Date(value));
75+
if (json.every(item => !(isNaN(parseDate(item).getTime())))) {
76+
return json.map(value => parseDate(value));
7477
}
7578
}
7679
{{/isDateType}}
7780
{{#isDateTimeType}}
7881
if (Array.isArray(json)) {
79-
if (json.every(item => !(isNaN(new Date(item).getTime())))) {
80-
return json.map(value => new Date(value));
82+
if (json.every(item => !(isNaN(parseDateTime(item).getTime())))) {
83+
return json.map(value => parseDateTime(value));
8184
}
8285
}
8386
{{/isDateTimeType}}
@@ -115,14 +118,14 @@ export function {{classname}}FromJSONTyped(json: any, ignoreDiscriminator: boole
115118
{{#oneOfPrimitives}}
116119
{{^isArray}}
117120
{{#isDateType}}
118-
if (!(isNaN(new Date(json).getTime()))) {
119-
return {{^required}}json == null ? undefined : {{/required}}({{#required}}{{#isNullable}}json == null ? null : {{/isNullable}}{{/required}}new Date(json));
121+
if (!(isNaN(parseDate(json).getTime()))) {
122+
return {{^required}}json == null ? undefined : {{/required}}({{#required}}{{#isNullable}}json == null ? null : {{/isNullable}}{{/required}}parseDate(json));
120123
}
121124
{{/isDateType}}
122125
{{^isDateType}}
123126
{{#isDateTimeType}}
124-
if (!(isNaN(new Date(json).getTime()))) {
125-
return {{^required}}json == null ? undefined : {{/required}}({{#required}}{{#isNullable}}json == null ? null : {{/isNullable}}{{/required}}new Date(json));
127+
if (!(isNaN(parseDateTime(json).getTime()))) {
128+
return {{^required}}json == null ? undefined : {{/required}}({{#required}}{{#isNullable}}json == null ? null : {{/isNullable}}{{/required}}parseDateTime(json));
126129
}
127130
{{/isDateTimeType}}
128131
{{/isDateType}}
@@ -195,14 +198,14 @@ export function {{classname}}ToJSONTyped(value?: {{classname}} | null, ignoreDis
195198
{{#isDateType}}
196199
if (Array.isArray(value)) {
197200
if (value.every(item => item instanceof Date)) {
198-
return value.map(value => value.toISOString().substring(0,10));
201+
return value.map(value => serializeDate(value));
199202
}
200203
}
201204
{{/isDateType}}
202205
{{#isDateTimeType}}
203206
if (Array.isArray(value)) {
204207
if (value.every(item => item instanceof Date)) {
205-
return value.map(item => item.toISOString());
208+
return value.map(item => serializeDateTime(item));
206209
}
207210
}
208211
{{/isDateTimeType}}
@@ -241,12 +244,12 @@ export function {{classname}}ToJSONTyped(value?: {{classname}} | null, ignoreDis
241244
{{^isArray}}
242245
{{#isDateType}}
243246
if (value instanceof Date) {
244-
return ((value{{#isNullable}} as any{{/isNullable}}){{^required}}{{#isNullable}}?{{/isNullable}}{{/required}}.toISOString().substring(0,10));
247+
return (serializeDate(value{{#isNullable}} as any{{/isNullable}}));
245248
}
246249
{{/isDateType}}
247250
{{#isDateTimeType}}
248251
if (value instanceof Date) {
249-
return {{^required}}{{#isNullable}}value === null ? null : {{/isNullable}}{{^isNullable}}value == null ? undefined : {{/isNullable}}{{/required}}((value{{#isNullable}} as any{{/isNullable}}){{^required}}{{#isNullable}}?{{/isNullable}}{{/required}}.toISOString());
252+
return {{^required}}{{#isNullable}}value === null ? null : {{/isNullable}}{{^isNullable}}value == null ? undefined : {{/isNullable}}{{/required}}(serializeDateTime(value{{#isNullable}} as any{{/isNullable}}));
250253
}
251254
{{/isDateTimeType}}
252255
{{#isNumeric}}

0 commit comments

Comments
 (0)