public static FlexiDateTime fromFudgeMsg(
     final FudgeDeserializer deserializer, final FudgeMsg msg) {
   if (msg == null) {
     return null;
   }
   final ZoneId zone = msg.getValue(ZoneId.class, ZONE_FIELD_NAME);
   final Object obj = msg.getValue(DATETIME_FIELD_NAME);
   if (obj instanceof FudgeDateTime) {
     FudgeDateTime fudge = (FudgeDateTime) obj;
     if (fudge.getTime().hasTimezoneOffset()) {
       OffsetDateTime odt = fudge.toOffsetDateTime();
       if (zone != null) {
         return FlexiDateTime.of(odt.atZoneSameInstant(zone));
       }
       return FlexiDateTime.of(odt);
     } else {
       return FlexiDateTime.of(fudge.toLocalDateTime());
     }
   } else if (obj instanceof FudgeDate) {
     FudgeDate fudge = (FudgeDate) obj;
     return FlexiDateTime.of(fudge.toLocalDate());
   } else if (obj instanceof OffsetDateTime) {
     OffsetDateTime odt = (OffsetDateTime) obj;
     if (zone != null) {
       return FlexiDateTime.of(odt.atZoneSameInstant(zone));
     }
     return FlexiDateTime.of(odt);
   } else if (obj instanceof LocalDateTime) {
     return FlexiDateTime.of((LocalDateTime) obj);
   } else if (obj instanceof LocalDate) {
     return FlexiDateTime.of((LocalDate) obj);
   } else {
     throw new IllegalStateException("Fudge message did not contain a valid date-time");
   }
 }
 public static void fromFudgeMsg(
     FudgeDeserializer deserializer, FudgeMsg msg, EquitySecurity object) {
   FinancialSecurityFudgeBuilder.fromFudgeMsg(deserializer, msg, object);
   object.setShortName(msg.getString(SHORT_NAME_FIELD_NAME));
   object.setExchange(msg.getString(EXCHANGE_FIELD_NAME));
   object.setExchangeCode(msg.getString(EXCHANGE_CODE_FIELD_NAME));
   object.setCompanyName(msg.getString(COMPANY_NAME_FIELD_NAME));
   object.setCurrency(msg.getValue(Currency.class, CURRENCY_FIELD_NAME));
   object.setGicsCode(msg.getValue(GICSCode.class, GICS_CODE_FIELD_NAME));
   object.setPreferred(BooleanUtils.isTrue(msg.getBoolean(PREFERRED_FIELD_NAME)));
 }
 public static void fromFudgeMsg(
     FudgeDeserializer deserializer, FudgeMsg msg, FXOptionSecurity object) {
   FinancialSecurityFudgeBuilder.fromFudgeMsg(deserializer, msg, object);
   object.setPutCurrency(msg.getValue(Currency.class, PUT_CURRENCY_FIELD_NAME));
   object.setCallCurrency(msg.getValue(Currency.class, CALL_CURRENCY_FIELD_NAME));
   object.setPutAmount(msg.getDouble(PUT_AMOUNT_FIELD_NAME));
   object.setCallAmount(msg.getDouble(CALL_AMOUNT_FIELD_NAME));
   object.setExpiry(
       ExpiryFudgeBuilder.fromFudgeMsg(deserializer, msg.getMessage(EXPIRY_FIELD_NAME)));
   object.setSettlementDate(
       ZonedDateTimeFudgeBuilder.fromFudgeMsg(
           deserializer, msg.getMessage(SETTLEMENT_DATE_FIELD_NAME)));
   object.setLongShort(LongShort.ofLong(msg.getBoolean(IS_LONG_FIELD_NAME)));
 }
 @Override
 public ZonedDateTime buildObject(FudgeDeserializationContext context, FudgeMsg msg) {
   final OffsetDateTime odt = msg.getValue(OffsetDateTime.class, ODT_FIELD_NAME);
   if (odt == null) {
     throw new IllegalArgumentException(
         "Fudge message is not a ZonedDateTime - field 'odt' is not present");
   }
   final String zone = msg.getString(ZONE_FIELD_NAME);
   if (zone == null) {
     throw new IllegalArgumentException(
         "Fudge message is not a ZonedDateTime - field 'zone' is not present");
   }
   return ZonedDateTime.of(odt, TimeZone.of(zone));
 }