Skip to content
GitLab
Projects Groups Snippets
  • /
  • Help
    • Help
    • Support
    • Community forum
    • Submit feedback
    • Contribute to GitLab
  • Sign in / Register
  • O openapi-generator
  • Project information
    • Project information
    • Activity
    • Labels
    • Members
  • Repository
    • Repository
    • Files
    • Commits
    • Branches
    • Tags
    • Contributors
    • Graph
    • Compare
  • Issues 3,476
    • Issues 3,476
    • List
    • Boards
    • Service Desk
    • Milestones
  • Merge requests 402
    • Merge requests 402
  • CI/CD
    • CI/CD
    • Pipelines
    • Jobs
    • Schedules
  • Deployments
    • Deployments
    • Environments
    • Releases
  • Packages and registries
    • Packages and registries
    • Package Registry
    • Infrastructure Registry
  • Monitor
    • Monitor
    • Incidents
  • Analytics
    • Analytics
    • Value stream
    • CI/CD
    • Repository
  • Wiki
    • Wiki
  • Snippets
    • Snippets
  • Activity
  • Graph
  • Create a new issue
  • Jobs
  • Commits
  • Issue Boards
Collapse sidebar
  • OpenAPI Tools
  • openapi-generator
  • Merge requests
  • !13519

[swift5] support both date and date-time formats

  • Review changes

  • Download
  • Email patches
  • Plain diff
Closed Administrator requested to merge github/fork/Jonas1893/feature/support-date-without-time-7.0 into 7.0.x Sep 25, 2022
  • Overview 4
  • Commits 4
  • Pipelines 0
  • Changes 126

Created by: Jonas1893

This PR adds support for openapi specs date format and fixes the points addressed in https://github.com/OpenAPITools/openapi-generator/issues/5280

Summary

In order to properly support OpenAPIs date type, I propose to introduce a new type because Swifts Date type alone is not sufficient - and neither is any other type from the Swift standard lib like DateComponents for reasons explained later. Sorry for the wall of text but dates, calendars and timezones are hard to reason about 😕

Because there is now a new type used in API Models this is a breaking change. We could create a new PR including only the changes from OpenISO8601DateFormatter to add support for decoding (but not encoding) date already in v6.*

Motivation

swift5 generator does map both OpenAPIs date and date-time formats to Swifts Date type. This is fine for date-time which is a specific point in time but can be problematic for date which is not a specific point in time but rather a time frame. OpenAPI spec defines data type date 'As defined by full-date - RFC3339' and RFC3339 defines a full-date basically as a day in the gregorian calendar.

Let's use an example. In an API where a request model defines a birthday property like this:

properties:
  birthday:
    type: date
    example: "2019-05-17"

swift5 generator would generate an API model with a property birthday with datatype Date. There are two problems here:

  1. Swift Dates always contain time information. The information for the generator whether the date should be encoded to date-time or just date format is therefor lost completely when using Date in the API models. That's why currently generator will always serialize Dates into date-time format.
  2. Even if we would know that we need to serialize into date and not date-time: Since Swifts Date is "A specific point in time, independent of any calendar or time zone.", any date (as a timeframe) supplied to the requst model MUST have been created using a gregorian calendar and timezone GMT+0. As soon as this is not the case and e.g. a date has been picked using a DatePicker in an iOS app using gregorian calendar but with a timezone offset of GMT+5 it is possible that the serialized Date is now in a different day on the gregorian calendar in GMT+0. So using this example, a wrong date would be sent to the server if this Date would be supplied without normalization to GMT+0.

The problem is more severe when encoding (sending something to a REST API) than in the decoding case, because when decoding we can safely assume ISO8601 standards are satisfied by the server and just try to decode multiple times using a different format. Still, a Date is being returned by the generator obfuscating the fact that this Date object including time information needs to be interpreted as "a full day in the gregorian calendar in timezone GMT+0". Knowledge of the API spec in addition to the generated code is currently required to properly interpret the Date in business logic of the consumer of the generated API.

Technical changes in this PR

  • New type DateWithoutTime is introduced for openapi specs date format which addresses the problems explained above. With the timezone information we can properly normalize to GMT+0. The new type enables generator logic to easily decide whether we need to encode to date or date-time.
  • New withoutTime formatter is added to custom OpenISO8601 formatter class using the same fallback mechanism as before when decoding dates. This change could also be contributed in a separate PR because it is backwards compatible and adds support for decoding(not encoding!) date to the generator.

Reasoning for the new type

The information whether a swagger attribute encodes to date or date-time somehow needs to be passed on from API models to generator logic. I tried fiddling with the models mustache templates (and we did this to workaround the current generator limitation in our project) but still we need to add this information for each attribute of type Date - so either we create tuples (which also breaks the existing APIs) or we create a new type.

Why not use DateComponents?

A lengthy discussion about why DateComponents are not suited for (de-)/encoding dates can be read here https://forums.swift.org/t/pitch-datecomponents-encoding-decoding-strategy-in-json-encoder-decoder/6602 In short and specific to our use case: DateComponents can be used to create Dates that do not exist or where days or month information can be omitted. They are therefor not suited to be used directly in our API models.

PR checklist

  • Read the contribution guidelines.
  • Pull Request title clearly describes the work in the pull request and Pull Request description provides details about how to validate the work. Missing information here may result in delayed response from the community.
  • Run the following to build the project and update samples:
    ./mvnw clean package
    ./bin/generate-samples.sh
    ./bin/utils/export_docs_generators.sh
    Commit all changed files. This is important, as CI jobs will verify all generator outputs of your HEAD commit as it would merge with master. These must match the expectations made by your contribution. You may regenerate an individual generator by passing the relevant config(s) as an argument to the script, for example ./bin/generate-samples.sh bin/configs/java*. For Windows users, please run the script in Git BASH.
  • File the PR against the correct branch: master (6.1.0) (minor release - breaking changes with fallbacks), 7.0.x (breaking changes without fallbacks)
  • If your PR is targeting a particular programming language, @mention the technical committee members, so they are more likely to review the pull request. -> @4brunu
Assignee
Assign to
Reviewers
Request review from
Time tracking
Source branch: github/fork/Jonas1893/feature/support-date-without-time-7.0