* @param out the output stream, not null
   * @throws IOException if an error occurs
   */
  void writeExternal(DataOutput out) throws IOException {

    final int timeSecs = (this.timeEndOfDay ? 86400 : this.time.toSecondOfDay());
    final int stdOffset = this.standardOffset.getTotalSeconds();
    final int beforeDiff = this.offsetBefore.getTotalSeconds() - stdOffset;
    final int afterDiff = this.offsetAfter.getTotalSeconds() - stdOffset;
    final int timeByte = (timeSecs % 3600 == 0 ? (this.timeEndOfDay ? 24 : this.time.getHour()) : 31);
    final int stdOffsetByte = (stdOffset % 900 == 0 ? stdOffset / 900 + 128 : 255);
    final int beforeByte = (beforeDiff == 0 || beforeDiff == 1800 || beforeDiff == 3600 ? beforeDiff / 1800 : 3);
    final int afterByte = (afterDiff == 0 || afterDiff == 1800 || afterDiff == 3600 ? afterDiff / 1800 : 3);
    final int dowByte = (this.dow == null ? 0 : this.dow.getValue());
    int b = (this.month.getValue() << 28) + // 4 bytes
        ((this.dom + 32) << 22) + // 6 bytes
        (dowByte << 19) + // 3 bytes
        (timeByte << 14) + // 5 bytes
        (this.timeDefinition.ordinal() << 12) + // 2 bytes
        (stdOffsetByte << 4) + // 8 bytes
        (beforeByte << 2) + // 2 bytes
        afterByte; // 2 bytes
    out.writeInt(b);
    if (timeByte == 31) {
      out.writeInt(timeSecs);
    }
    if (stdOffsetByte == 255) {
      out.writeInt(stdOffset);
    }
    if (beforeByte == 3) {
      out.writeInt(this.offsetBefore.getTotalSeconds());
    }
    if (afterByte == 3) {
      out.writeInt(this.offsetAfter.getTotalSeconds());
    }
  }