title: Instant vs ZonedDateTime
body: <p>I just do not quite understand which one of those two I should use for the following example:</p>
  
  <p>We have an <code>OfferEntity</code> which has a member <code>availableDay</code> which is the date at which the offer is available. </p>
  
  <p>Now, the table will look something like this:</p>
  
  <pre class="lang-sql prettyprint-override"><code>CREATE TABLE IF NOT EXISTS offer (
    created   timestamp with time zone NOT NULL DEFAULT NOW(),
    id        BIGSERIAL PRIMARY KEY,
    available timestamp with time zone
  );
  </code></pre>
  
  <p>From the <a href="https://www.postgresql.org/docs/current/static/datatype-datetime.html#AEN5811" rel="noreferrer">PostgreSQL docs</a> we know that:</p>
  
  <blockquote>
    <p>For <code>timestamp with time zone</code>, the internally stored value is always in UTC (Universal Coordinated Time, traditionally known as Greenwich Mean Time, GMT). An input value that has an explicit time zone specified is converted to UTC using the appropriate offset for that time zone. If no time zone is stated in the input string, then it is assumed to be in the time zone indicated by the system's <code>TimeZone</code> parameter, and is converted to UTC using the offset for the timezone zone.</p>
  </blockquote>
  
  <p>Which means I should be fine when it comes to persisting any date/time information.</p>
  
  <p>But what does this mean for my <code>OfferEntity</code> and the REST endpoints I define in <code>OfferController</code>?</p>
  
  <pre class="lang-java prettyprint-override"><code>@Entity
  @Table(name = "offer")
  public class OfferEntity {    
      @Column(name = "available", nullable = false)
      private ZonedDateTime availableDay;
  }
  </code></pre>
  
  <p>vs</p>
  
  <pre class="lang-java prettyprint-override"><code>@Entity
  @Table(name = "offer")
  public class OfferEntity {    
      @Column(name = "available", nullable = false)
      private Instant availableDay;
  }
  </code></pre>
  
  <p>From what I understood - this should not make a difference. PostgreSQL stores everything as UTC anyway so I should be able to take <code>Instant</code> or <code>ZonedDateTime</code> right? Write something -> UTC. Read it again -> still UTC.</p>
  
  <p>Even the client won't be able to tell the difference:</p>
  
  <pre class="lang-java prettyprint-override"><code>@RequestMapping(value = "/hello", method = RequestMethod.GET)
  public Object hello() {
  
      class Hello {
          public Instant instant = Instant.now();
          public ZonedDateTime zonedDateTime = ZonedDateTime.now();
          public ZonedDateTime viennaTime = ZonedDateTime.now(ZoneId.of("GMT+2"));
          public LocalDateTime localDateTime = LocalDateTime.now();
      }
  
      return new Hello();
  }
  </code></pre>
  
  <p>Will return:</p>
  
  <pre><code>{
    "instant":       "2018-10-07T15:30:08.579Z",
    "zonedDateTime": "2018-10-07T15:30:08.579Z",
    "viennaTime":    "2018-10-07T17:30:08.579+02:00",
    "localDateTime": "2018-10-07T15:30:08.579",
  }
  </code></pre>
  
  <p>But there must be a crucial difference which I am apparently not seeing.</p>
  
  <hr>
  
  <p>There are two differences I can make out. It seems to be that Spring has no problem with converting <code>"2018-10-07T15:30:08.579Z"</code> to an <code>Instant</code> object, but fails to do so if I change the type to <code>ZonedDateTime</code>. At least out of the box.</p>
  
  <pre class="lang-java prettyprint-override"><code>@RequestMapping("/places/{placeId}/offers", method = RequestMethod.GET)
  public List&lt;OfferDto&gt; getOffers(
          @PathVariable(name = "placeId") Long placeId,
          @RequestParam(name = "date") ZonedDateTime date) {
      return this.offerService.getOffers(placeId, date);
  }
  </code></pre>
  
  <p>The other difference is the fact that if I use <code>Instant</code> I am forcing my clients to convert all their date/time strings to UTC first. So any client will have to <code>myDate.toUTCString()</code> first. <code>ZonedDateTime</code> would take anything as long as it has a time zone set but why would we care? </p>
  
  <hr>
  
  <p>So which of the two is the better choice and why would I chose one over the other?</p>