title: Mapping 2 String fields to OffsetDateTime with MapStruct
body: <p>I have the following DTO which has 2 fields that must be converted to OffsetDateTime:</p>
  
  <pre><code>@Data
  public class AppointmentDTO {
  
      private String id;
  
      @NotNull
      private String startTime;
  
      @NotNull
      private String endTime;
  
      @NotNull
      private String timeZoneStart;
  
      @NotNull
      private String timeZoneEnd;
  
      // other fields
  } 
  </code></pre>
  
  <p>to</p>
  
  <pre><code>@Data
  @Document
  @NoArgsConstructor
  @AllArgsConstructor
  public class Appointment {
  
      @Id
      private String id;
  
      private String timeZoneStart;
      private String timeZoneEnd;
      private OffsetDateTime startTime;
      private OffsetDateTime endTime;
      private OffsetDateTime createdTime;
      // other fields
  }
  </code></pre>
  
  <p>In order to convert, I need the DTO's <code>timeZone</code> fields plus a <code>DateTimeFormatter</code>. So, my attempt is this:</p>
  
  <pre><code>@Component
  @Mapper(componentModel = "spring")
  public interface IAppointmentMapper {
  
      @Mapping(target = "createdTime", ignore = true)
      Appointment convertAppointmentDTOToAppointment(AppointmentDTO dto, @Context OffsetDateTimeMapper offsetDateTimeMapper);
  }
  </code></pre>
  
  <pre><code>public class OffsetDateTimeMapper {
  
      private String startTime;
      private String endTime;
      private String timeZoneStart;
      private String timeZoneEnd;
      private final DateTimeFormatter dateTimeFormatter;
  
      public OffsetDateTimeMapper(DateTimeFormatter dateTimeFormatter) {
          this.dateTimeFormatter = dateTimeFormatter;
      }
  
      @BeforeMapping
      public void beforeStartTimeMapping(AppointmentDTO dto) {
          this.startTime = dto.getStartTime();
          this.timeZoneStart = dto.getTimeZoneStart();
      }
  
      @BeforeMapping
      public void beforeEndTimeMapping(AppointmentDTO dto) {
          this.endTime = dto.getEndTime();
          this.timeZoneEnd = dto.getTimeZoneEnd();
      }
  
      @AfterMapping
      public void startTimeMap(@MappingTarget Appointment appointment) {
          LocalDateTime localDateTime = LocalDateTime.parse(startTime, dateTimeFormatter);
          ZonedDateTime zonedDateTime = localDateTime.atZone(ZoneId.of(timeZoneStart));
          appointment.setStartTime(zonedDateTime.toOffsetDateTime());
      }
  
      @AfterMapping
      public void endTimeMap(@MappingTarget Appointment appointment) {
          LocalDateTime localDateTime = LocalDateTime.parse(endTime, dateTimeFormatter);
          ZonedDateTime zonedDateTime = localDateTime.atZone(ZoneId.of(timeZoneEnd));
          appointment.setEndTime(zonedDateTime.toOffsetDateTime());
      }
  }
  </code></pre>
  
  <p>When I build, however, I get the following error: <code>Error:(22,17) java: Can't map property "java.lang.String startTime" to "java.time.OffsetDateTime startTime". Consider to declare/implement a mapping method: "java.time.OffsetDateTime map(java.lang.String value)".</code> If I put a <code>default map()</code> method on the interface, I don't get the error, but I don't have the proper <code>@Context</code> required.</p>
  
  <pre><code>/*default OffsetDateTime map(String value) {
       LocalDateTime localDateTime = LocalDateTime.parse(value);
       ZonedDateTime zonedDateTime = localDateTime.atZone(ZoneOffset.UTC);
       return zonedDateTime.toOffsetDateTime();
  }*/
  </code></pre>