You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@daffodil.apache.org by GitBox <gi...@apache.org> on 2018/07/25 20:34:55 UTC

[GitHub] efinnegan closed pull request #83: Adding value of 'bcd' to binaryCalendarRep

efinnegan closed pull request #83: Adding value of 'bcd' to binaryCalendarRep
URL: https://github.com/apache/incubator-daffodil/pull/83
 
 
   

This is a PR merged from a forked repository.
As GitHub hides the original diff on merge, it is displayed below for
the sake of provenance:

As this is a foreign pull request (from a fork), the diff is supplied
below (as it won't show otherwise due to GitHub magic):

diff --git a/daffodil-core/src/main/scala/org/apache/daffodil/grammar/ElementBaseGrammarMixin.scala b/daffodil-core/src/main/scala/org/apache/daffodil/grammar/ElementBaseGrammarMixin.scala
index e83e40a50..17129af26 100644
--- a/daffodil-core/src/main/scala/org/apache/daffodil/grammar/ElementBaseGrammarMixin.scala
+++ b/daffodil-core/src/main/scala/org/apache/daffodil/grammar/ElementBaseGrammarMixin.scala
@@ -30,6 +30,15 @@ import org.apache.daffodil.dsom.ExpressionCompilers
 import org.apache.daffodil.dsom.InitiatedTerminatedMixin
 import org.apache.daffodil.exceptions.Assert
 import org.apache.daffodil.grammar.primitives.AlignmentFill
+import org.apache.daffodil.grammar.primitives.BCDDateKnownLengthPrim
+import org.apache.daffodil.grammar.primitives.BCDDateRuntimeLengthPrim
+import org.apache.daffodil.grammar.primitives.BCDDateTimeKnownLengthPrim
+import org.apache.daffodil.grammar.primitives.BCDDateTimeRuntimeLengthPrim
+import org.apache.daffodil.grammar.primitives.BCDTimeKnownLengthPrim
+import org.apache.daffodil.grammar.primitives.BCDTimeRuntimeLengthPrim
+import org.apache.daffodil.grammar.primitives.BCDTimeDelimitedLengthPrim
+import org.apache.daffodil.grammar.primitives.BCDDateTimeDelimitedLengthPrim
+import org.apache.daffodil.grammar.primitives.BCDDateDelimitedLengthPrim
 import org.apache.daffodil.grammar.primitives.BCDDecimalDelimitedEndOfData
 import org.apache.daffodil.grammar.primitives.BCDDecimalKnownLength
 import org.apache.daffodil.grammar.primitives.BCDDecimalRuntimeLength
@@ -130,6 +139,7 @@ import org.apache.daffodil.schema.annotation.props.NotFound
 import org.apache.daffodil.schema.annotation.props.gen.BinaryCalendarRep
 import org.apache.daffodil.schema.annotation.props.gen.BinaryFloatRep
 import org.apache.daffodil.schema.annotation.props.gen.BinaryNumberRep
+import org.apache.daffodil.schema.annotation.props.gen.CalendarPatternKind
 import org.apache.daffodil.schema.annotation.props.gen.LengthKind
 import org.apache.daffodil.schema.annotation.props.gen.LengthUnits
 import org.apache.daffodil.schema.annotation.props.gen.NilKind
@@ -496,8 +506,14 @@ trait ElementBaseGrammarMixin
     case LengthKind.Implicit => implicitBinaryLengthInBits
     case LengthKind.Explicit if (lengthEv.isConstant) => explicitBinaryLengthInBits()
     case LengthKind.Explicit => -1 // means must be computed at runtime.
-    case LengthKind.Delimited if (binaryNumberRep == BinaryNumberRep.Binary) => subsetError("lengthKind='delimited' only supported for packed binary formats.")
-    case LengthKind.Delimited => -1 // only for packed binary data, length must be computed at runtime.
+    case LengthKind.Delimited => primType match {
+      case PrimType.DateTime | PrimType.Date | PrimType.Time =>
+        if (binaryCalendarRep == BinaryCalendarRep.BinaryMilliseconds || binaryCalendarRep == BinaryCalendarRep.BinarySeconds)
+          subsetError("lengthKind='delimited' only supported for packed binary formats.")
+        else -1 // only for packed binary data, length must be computed at runtime.
+      case _ => if (binaryNumberRep == BinaryNumberRep.Binary) subsetError("lengthKind='delimited' only supported for packed binary formats.")
+        else -1 // only for packed binary data, length must be computed at runtime.
+    }
     case LengthKind.Pattern => schemaDefinitionError("Binary data elements cannot have lengthKind='pattern'.")
     case LengthKind.Prefixed => subsetError("lengthKind='prefixed' not yet supported.")
     case LengthKind.EndOfParent => schemaDefinitionError("Binary data elements cannot have lengthKind='endOfParent'.")
@@ -829,7 +845,26 @@ trait ElementBaseGrammarMixin
             case (_, n) => SDE("binary xs:dateTime must be 64 bits when binaryCalendarRep='binaryMilliseconds'. Length in bits was %s.", n)
           }
           case (_, BinaryCalendarRep.BinaryMilliseconds) => SDE("binaryCalendarRep='binaryMilliseconds' is not allowed with type %s", primType.name)
-          case _ => notYetImplemented("Type %s when representation='binary' and binaryCalendarRep=%s", primType.name, binaryCalendarRep.toString)
+          case (_, BinaryCalendarRep.Bcd) => {
+            if ((binaryNumberKnownLengthInBits != -1) && (binaryNumberKnownLengthInBits % 4) != 0)
+              SDE("The given length (%s bits) must be a multiple of 4 when using binaryCalendarRep='%s'.", binaryNumberKnownLengthInBits, binaryCalendarRep)
+            if (calendarPatternKind != CalendarPatternKind.Explicit)
+              SDE("calendarPatternKind must be 'explicit' when binaryCalendarRep='%s'", binaryCalendarRep)
+
+            (primType, lengthKind, binaryNumberKnownLengthInBits) match {
+              case (PrimType.DateTime, LengthKind.Delimited, -1) => new BCDDateTimeDelimitedLengthPrim(this)
+              case (PrimType.DateTime, _, -1) => new BCDDateTimeRuntimeLengthPrim(this)
+              case (PrimType.DateTime, _, _) => new BCDDateTimeKnownLengthPrim(this, binaryNumberKnownLengthInBits)
+              case (PrimType.Date, LengthKind.Delimited, -1) => new BCDDateDelimitedLengthPrim(this)
+              case (PrimType.Date, _, -1) => new BCDDateRuntimeLengthPrim(this)
+              case (PrimType.Date, _, _) => new BCDDateKnownLengthPrim(this, binaryNumberKnownLengthInBits)
+              case (PrimType.Time, LengthKind.Delimited, -1) => new BCDTimeDelimitedLengthPrim(this)
+              case (PrimType.Time, _, -1) => new BCDTimeRuntimeLengthPrim(this)
+              case (PrimType.Time, _, _) => new BCDTimeKnownLengthPrim(this, binaryNumberKnownLengthInBits)
+              case _ => SDE("Invalid case.")
+            }
+          }
+          case _ =>  notYetImplemented("Type %s when representation='binary' and binaryCalendarRep=%s", primType.name, binaryCalendarRep.toString)
         }
       }
 
diff --git a/daffodil-core/src/main/scala/org/apache/daffodil/grammar/primitives/PrimitivesDateTime.scala b/daffodil-core/src/main/scala/org/apache/daffodil/grammar/primitives/PrimitivesDateTime.scala
index e6f275e6e..235df44cb 100644
--- a/daffodil-core/src/main/scala/org/apache/daffodil/grammar/primitives/PrimitivesDateTime.scala
+++ b/daffodil-core/src/main/scala/org/apache/daffodil/grammar/primitives/PrimitivesDateTime.scala
@@ -23,16 +23,23 @@ import com.ibm.icu.util.Calendar
 import com.ibm.icu.util.TimeZone
 import com.ibm.icu.util.ULocale
 import org.apache.daffodil.dsom.ElementBase
+import org.apache.daffodil.exceptions.Assert
 import org.apache.daffodil.grammar.Terminal
 import org.apache.daffodil.schema.annotation.props.gen.CalendarCheckPolicy
 import org.apache.daffodil.schema.annotation.props.gen.CalendarFirstDayOfWeek
 import org.apache.daffodil.schema.annotation.props.gen.CalendarPatternKind
+import org.apache.daffodil.processors.unparsers.BinaryCalendarBCDRuntimeLengthUnparser
+import org.apache.daffodil.processors.unparsers.BinaryCalendarBCDKnownLengthUnparser
+import org.apache.daffodil.processors.unparsers.BinaryCalendarBCDDelimitedLengthUnparser
 import org.apache.daffodil.processors.unparsers.ConvertBinaryCalendarSecMilliUnparser
 import org.apache.daffodil.processors.unparsers.ConvertTextCalendarUnparser
 import com.ibm.icu.util.Calendar
 import com.ibm.icu.util.TimeZone
 import org.apache.daffodil.processors.CalendarEv
 import org.apache.daffodil.processors.CalendarLanguageEv
+import org.apache.daffodil.processors.parsers.BinaryCalendarBCDDelimitedLengthParser
+import org.apache.daffodil.processors.parsers.BinaryCalendarBCDKnownLengthParser
+import org.apache.daffodil.processors.parsers.BinaryCalendarBCDRuntimeLengthParser
 import org.apache.daffodil.processors.parsers.ConvertBinaryCalendarSecMilliParser
 import org.apache.daffodil.processors.parsers.ConvertTextCalendarParser
 import org.apache.daffodil.processors.parsers.TextCalendarConstants
@@ -47,32 +54,12 @@ abstract class ConvertCalendarPrimBase(e: ElementBase, guard: Boolean)
   override def toString = "to(xs:" + xsdType + ")"
 }
 
-abstract class ConvertTextCalendarPrimBase(e: ElementBase, guard: Boolean)
-  extends ConvertCalendarPrimBase(e, guard) {
+trait CalendarPrimBase {
+  def e: ElementBase
 
   protected def infosetPattern: String
-  protected def implicitPattern: String
   protected def validFormatCharacters: Seq[Char]
-
-  lazy val pattern: String = {
-    val p = e.calendarPatternKind match {
-      case CalendarPatternKind.Explicit => e.calendarPattern
-      case CalendarPatternKind.Implicit => implicitPattern
-    }
-
-    val escapedText = "(''|'[^']+'|[^a-zA-Z])".r
-    val patternNoEscapes = escapedText.replaceAllIn(p, "")
-    patternNoEscapes.toSeq.foreach(char =>
-      if (!validFormatCharacters.contains(char)) {
-        SDE("Character '%s' not allowed in dfdl:calendarPattern for xs:%s".format(char, xsdType))
-      })
-
-    if (patternNoEscapes.indexOf("S" * (TextCalendarConstants.maxFractionalSeconds + 1)) >= 0) {
-      SDE("More than %d fractional seconds unsupported in dfdl:calendarPattern for xs:%s".format(TextCalendarConstants.maxFractionalSeconds, xsdType))
-    }
-
-    p
-  }
+  protected def pattern: String
 
   val firstDay = e.calendarFirstDayOfWeek match {
     case CalendarFirstDayOfWeek.Sunday => Calendar.SUNDAY
@@ -134,17 +121,44 @@ abstract class ConvertTextCalendarPrimBase(e: ElementBase, guard: Boolean)
     res
   }
 
-  private lazy val localeEv = {
+  protected lazy val localeEv = {
     val ev = new CalendarLanguageEv(e.calendarLanguage, e.erd)
     ev.compile()
     ev
   }
 
-  private lazy val calendarEv = {
+  protected lazy val calendarEv = {
     val cev = new CalendarEv(localeEv, calendarTz, firstDay, calendarDaysInFirstWeek, calendarCheckPolicy, e.erd)
     cev.compile()
     cev
   }
+}
+
+abstract class ConvertTextCalendarPrimBase(e: ElementBase, guard: Boolean)
+  extends ConvertCalendarPrimBase(e, guard)
+  with CalendarPrimBase {
+
+  protected def implicitPattern: String
+
+  lazy val pattern: String = {
+    val p = e.calendarPatternKind match {
+      case CalendarPatternKind.Explicit => e.calendarPattern
+      case CalendarPatternKind.Implicit => implicitPattern
+    }
+
+    val escapedText = "(''|'[^']+'|[^a-zA-Z])".r
+    val patternNoEscapes = escapedText.replaceAllIn(p, "")
+    patternNoEscapes.toSeq.foreach(char =>
+      if (!validFormatCharacters.contains(char)) {
+        SDE("Character '%s' not allowed in dfdl:calendarPattern for xs:%s".format(char, xsdType))
+      })
+
+    if (patternNoEscapes.indexOf("S" * (TextCalendarConstants.maxFractionalSeconds + 1)) >= 0) {
+      SDE("More than %d fractional seconds unsupported in dfdl:calendarPattern for xs:%s".format(TextCalendarConstants.maxFractionalSeconds, xsdType))
+    }
+
+    p
+  }
 
   override lazy val parser = new ConvertTextCalendarParser(
     e.elementRuntimeData,
@@ -186,9 +200,27 @@ case class ConvertTextDateTimePrim(e: ElementBase) extends ConvertTextCalendarPr
   protected override val validFormatCharacters = "adDeEFGhHkKmMsSuwWvVyXxYzZ".toSeq
 }
 
-abstract class ConvertBinaryCalendarPrimBase(e: ElementBase, guard: Boolean, lengthInBits: Long)
-  extends ConvertCalendarPrimBase(e, guard) {
+abstract class BinaryPackedDecimalCalendarPrimBase(e: ElementBase, guard: Boolean)
+  extends ConvertCalendarPrimBase(e, guard)
+  with CalendarPrimBase {
 
+  lazy val pattern: String = {
+    val p = e.calendarPatternKind match {
+      case CalendarPatternKind.Explicit => e.calendarPattern
+      case _ => Assert.impossibleCase
+    }
+
+    p.toSeq.foreach(char =>
+      if (!validFormatCharacters.contains(char)) {
+        SDE("Character '%s' not allowed in dfdl:calendarPattern for xs:%s with a binaryCalendarRep of '%s'".format(char, xsdType, e.binaryCalendarRep))
+      })
+
+    if (p.indexOf("S" * (TextCalendarConstants.maxFractionalSeconds + 1)) >= 0) {
+      SDE("More than %d fractional seconds unsupported in dfdl:calendarPattern for xs:%s".format(TextCalendarConstants.maxFractionalSeconds, xsdType))
+    }
+
+    p
+  }
 }
 
 case class ConvertBinaryDateTimeSecMilliPrim(e: ElementBase, lengthInBits: Long) extends ConvertCalendarPrimBase(e, true) {
@@ -243,3 +275,155 @@ case class ConvertBinaryDateTimeSecMilliPrim(e: ElementBase, lengthInBits: Long)
     lengthInBits.toInt,
     !epochCalendar.getTimeZone.equals(TimeZone.UNKNOWN_ZONE))
 }
+
+abstract class BCDRuntimeLength(e: ElementBase) extends BinaryPackedDecimalCalendarPrimBase(e, true) {
+
+  override lazy val parser = new BinaryCalendarBCDRuntimeLengthParser(
+    e.elementRuntimeData,
+    false,
+    pattern,
+    localeEv,
+    calendarEv,
+    xsdType,
+    prettyType,
+    e.lengthEv,
+    e.lengthUnits)
+
+  override lazy val unparser =
+    new BinaryCalendarBCDRuntimeLengthUnparser(
+    e.elementRuntimeData,
+    pattern,
+    localeEv,
+    calendarEv,
+    e.lengthEv,
+    e.lengthUnits)
+}
+
+abstract class BCDKnownLength(e: ElementBase, lengthInBits: Long) extends BinaryPackedDecimalCalendarPrimBase(e, true) {
+
+  override lazy val parser = new BinaryCalendarBCDKnownLengthParser(
+    e.elementRuntimeData,
+    false,
+    lengthInBits.toInt,
+    pattern,
+    localeEv,
+    calendarEv,
+    xsdType,
+    prettyType)
+
+  override lazy val unparser =
+    new BinaryCalendarBCDKnownLengthUnparser(
+    e.elementRuntimeData,
+    lengthInBits.toInt,
+    pattern,
+    localeEv,
+    calendarEv)
+}
+
+abstract class BCDDelimitedLength(e: ElementBase, xsdType: String, prettyType: String)
+  extends StringDelimited(e)
+  with CalendarPrimBase {
+
+  lazy val pattern: String = {
+    val p = e.calendarPatternKind match {
+      case CalendarPatternKind.Explicit => e.calendarPattern
+      case _ => Assert.impossibleCase
+    }
+
+    p.toSeq.foreach(char =>
+      if (!validFormatCharacters.contains(char)) {
+        SDE("Character '%s' not allowed in dfdl:calendarPattern for xs:%s with a binaryCalendarRep of '%s'".format(char, xsdType, e.binaryCalendarRep))
+      })
+
+    if (p.indexOf("S" * (TextCalendarConstants.maxFractionalSeconds + 1)) >= 0) {
+      SDE("More than %d fractional seconds unsupported in dfdl:calendarPattern for xs:%s".format(TextCalendarConstants.maxFractionalSeconds, xsdType))
+    }
+
+    p
+  }
+
+  val isDelimRequired: Boolean = false
+
+  override lazy val parser = new BinaryCalendarBCDDelimitedLengthParser(
+    e.elementRuntimeData,
+    false,
+    pattern,
+    localeEv,
+    calendarEv,
+    xsdType,
+    prettyType,
+    textDelimitedParser,
+    fieldDFAParseEv,
+    isDelimRequired)
+
+  override lazy val unparser =
+    new BinaryCalendarBCDDelimitedLengthUnparser(
+    e.elementRuntimeData,
+    pattern,
+    localeEv,
+    calendarEv)
+
+}
+
+case class BCDDateKnownLengthPrim(e: ElementBase, lengthInBits: Long)
+    extends BCDKnownLength(e, lengthInBits) {
+  protected override val xsdType = "date"
+  protected override val prettyType = "Date"
+  protected override val infosetPattern = "uuuu-MM-ddxxx"
+  protected override val validFormatCharacters = "dDeEFGMuwWyXxYzZ".toSeq
+}
+
+case class BCDDateRuntimeLengthPrim(e: ElementBase) extends BCDRuntimeLength(e) {
+  protected override val xsdType = "date"
+  protected override val prettyType = "Date"
+  protected override val infosetPattern = "uuuu-MM-ddxxx"
+  protected override val validFormatCharacters = "dDeEFGMuwWyXxYzZ".toSeq
+}
+
+case class BCDDateDelimitedLengthPrim(e: ElementBase)
+    extends BCDDelimitedLength(e, "date", "Date") {
+  protected override val infosetPattern = "uuuu-MM-ddxxx"
+  protected override val validFormatCharacters = "dDeEFGMuwWyXxYzZ".toSeq
+}
+
+case class BCDTimeKnownLengthPrim(e: ElementBase, lengthInBits: Long)
+    extends BCDKnownLength(e, lengthInBits) {
+  protected override val xsdType = "time"
+  protected override val prettyType = "Time"
+  protected override val infosetPattern = "HH:mm:ss.SSSSSSxxx"
+  protected override val validFormatCharacters = "ahHkKmsSvVzXxZ".toSeq
+}
+
+case class BCDTimeRuntimeLengthPrim(e: ElementBase) extends BCDRuntimeLength(e) {
+  protected override val xsdType = "time"
+  protected override val prettyType = "Time"
+  protected override val infosetPattern = "HH:mm:ss.SSSSSSxxx"
+  protected override val validFormatCharacters = "ahHkKmsSvVzXxZ".toSeq
+}
+
+case class BCDTimeDelimitedLengthPrim(e: ElementBase)
+    extends BCDDelimitedLength(e, "time", "Time") {
+  protected override val infosetPattern = "HH:mm:ss.SSSSSSxxx"
+  protected override val validFormatCharacters = "ahHkKmsSvVzXxZ".toSeq
+}
+
+case class BCDDateTimeKnownLengthPrim(e: ElementBase, lengthInBits: Long)
+    extends BCDKnownLength(e, lengthInBits) {
+  protected override val xsdType = "dateTime"
+  protected override val prettyType = "DateTime"
+  protected override val infosetPattern = "uuuu-MM-dd'T'HH:mm:ss.SSSSSSxxx"
+  protected override val validFormatCharacters = "adDeEFGhHkKmMsSuwWvVyXxYzZ".toSeq
+}
+
+case class BCDDateTimeRuntimeLengthPrim(e: ElementBase) extends BCDRuntimeLength(e) {
+  protected override val xsdType = "dateTime"
+  protected override val prettyType = "DateTime"
+  protected override val infosetPattern = "uuuu-MM-dd'T'HH:mm:ss.SSSSSSxxx"
+  protected override val validFormatCharacters = "adDeEFGhHkKmMsSuwWvVyXxYzZ".toSeq
+}
+
+case class BCDDateTimeDelimitedLengthPrim(e: ElementBase)
+    extends BCDDelimitedLength(e, "dateTime", "DateTime") {
+  protected override val infosetPattern = "uuuu-MM-dd'T'HH:mm:ss.SSSSSSxxx"
+  protected override val validFormatCharacters = "adDeEFGhHkKmMsSuwWvVyXxYzZ".toSeq
+}
diff --git a/daffodil-runtime1-unparser/src/main/scala/org/apache/daffodil/processors/unparsers/ConvertBinaryCalendarUnparser.scala b/daffodil-runtime1-unparser/src/main/scala/org/apache/daffodil/processors/unparsers/ConvertBinaryCalendarUnparser.scala
index f948c2286..397739162 100644
--- a/daffodil-runtime1-unparser/src/main/scala/org/apache/daffodil/processors/unparsers/ConvertBinaryCalendarUnparser.scala
+++ b/daffodil-runtime1-unparser/src/main/scala/org/apache/daffodil/processors/unparsers/ConvertBinaryCalendarUnparser.scala
@@ -17,16 +17,29 @@
 
 package org.apache.daffodil.processors.unparsers
 
+import java.lang.{ Long => JLong }
+import java.math.{ BigDecimal => JBigDecimal }
+import java.math.{ BigInteger => JBigInteger }
+
 import org.apache.daffodil.calendar.DFDLCalendar
 import org.apache.daffodil.exceptions.Assert
 import org.apache.daffodil.io.DataOutputStream
 import org.apache.daffodil.io.FormatInfo
+import org.apache.daffodil.processors.CalendarEv
+import org.apache.daffodil.processors.CalendarLanguageEv
 import org.apache.daffodil.processors.ElementRuntimeData
+import org.apache.daffodil.processors.Evaluatable
+import org.apache.daffodil.processors.parsers.ConvertTextCalendarProcessorBase
+import org.apache.daffodil.processors.parsers.HasKnownLengthInBits
+import org.apache.daffodil.processors.parsers.HasRuntimeExplicitLength
 import org.apache.daffodil.schema.annotation.props.gen.BinaryCalendarRep
+import org.apache.daffodil.schema.annotation.props.gen.LengthUnits
+import org.apache.daffodil.util.DecimalUtils
 import org.apache.daffodil.util.Maybe.One
 import org.apache.daffodil.util.Misc
 
 import com.ibm.icu.util.Calendar
+import com.ibm.icu.util.ULocale
 
 case class ConvertBinaryCalendarSecMilliUnparser(
   override val context: ElementRuntimeData,
@@ -51,7 +64,7 @@ case class ConvertBinaryCalendarSecMilliUnparser(
 
     val calValue = node.dataValue match {
       case dc: DFDLCalendar => dc.calendar
-      case x => Assert.invariantFailed("ConvertTextCalendar received unsupported type. %s of type %s.".format(x, Misc.getNameFromClass(x)))
+      case x => Assert.invariantFailed("ConvertBinaryCalendar received unsupported type. %s of type %s.".format(x, Misc.getNameFromClass(x)))
     }
 
     // Adjust the time based on time zone - if a time zone wasn't specified, Calendar will assume the default
@@ -82,3 +95,110 @@ case class ConvertBinaryCalendarSecMilliUnparser(
     }
   }
 }
+
+abstract class BinaryCalendarBCDUnparser (
+  override val context: ElementRuntimeData,
+  pattern: String,
+  localeEv: CalendarLanguageEv,
+  calendarEv: CalendarEv)
+  extends ConvertTextCalendarProcessorBase {
+
+  protected def fromBigInteger(bigInt: JBigInteger, nBits: Int): Array[Byte] = DecimalUtils.bcdFromBigInteger(bigInt, nBits)
+
+  protected def putNumber(dos: DataOutputStream, bigDec: JBigDecimal, nBits: Int, finfo: FormatInfo): Boolean = {
+    val packedNum = fromBigInteger(bigDec.unscaledValue, nBits)
+    dos.putByteArray(packedNum, packedNum.length * 8, finfo)
+  }
+
+  def doUnparse(state: UState, bitLength: Int): Unit = {
+
+    val locale: ULocale = localeEv.evaluate(state)
+    val calendar: Calendar = calendarEv.evaluate(state)
+
+    calendar.clear()
+
+    val df = tlDataFormatter(locale, calendar)
+    df.setCalendar(calendar)
+
+    val node = state.currentInfosetNode.asSimple
+
+    val calValue = node.dataValue match {
+      case dc: DFDLCalendar => dc.calendar
+      case x => Assert.invariantFailed("ConvertBinaryCalendar received unsupported type. %s of type %s.".format(x, Misc.getNameFromClass(x)))
+    }
+
+    val str: String = df.format(calValue)
+
+    val strAsBigDec: JBigDecimal = DecimalUtils.bcdToBigDecimal(DecimalUtils.bcdFromBigInteger(new JBigInteger(str), 0), 0)
+
+    val dos = state.dataOutputStream
+    val res = putNumber(dos, strAsBigDec, bitLength, state)
+
+    if (!res) {
+      Assert.invariant(dos.maybeRelBitLimit0b.isDefined)
+      UnparseError(One(state.schemaFileLocation), One(state.currentLocation), "Insufficient space to unparse element %s, required %s bits, but only %s were available.",
+        context.dpathElementCompileInfo.namedQName.toPrettyString, bitLength, dos.maybeRelBitLimit0b.get)
+    }
+  }
+}
+
+case class BinaryCalendarBCDKnownLengthUnparser(
+  override val context: ElementRuntimeData,
+  lengthInBits: Int,
+  pattern: String,
+  localeEv: CalendarLanguageEv,
+  calendarEv: CalendarEv)
+  extends BinaryCalendarBCDUnparser(context, pattern, localeEv, calendarEv)
+  with PrimUnparser
+  with HasKnownLengthInBits {
+
+  /**
+   * Primitive unparsers must override runtimeDependencies
+   */
+  override lazy val runtimeDependencies = Seq(localeEv, calendarEv)
+
+  def unparse(state: UState): Unit = {
+    doUnparse(state, lengthInBits)
+  }
+}
+
+case class BinaryCalendarBCDRuntimeLengthUnparser(
+  override val e: ElementRuntimeData,
+  pattern: String,
+  localeEv: CalendarLanguageEv,
+  calendarEv: CalendarEv,
+  val lengthEv: Evaluatable[JLong],
+  val lUnits: LengthUnits)
+  extends BinaryCalendarBCDUnparser(e, pattern, localeEv, calendarEv)
+  with PrimUnparser
+  with HasRuntimeExplicitLength {
+
+  /**
+   * Primitive unparsers must override runtimeDependencies
+   */
+  override lazy val runtimeDependencies = Seq(localeEv, calendarEv, lengthEv)
+
+  def unparse(state: UState): Unit = {
+    doUnparse(state, getBitLength(state))
+  }
+
+}
+
+case class BinaryCalendarBCDDelimitedLengthUnparser(
+  val e: ElementRuntimeData,
+  pattern: String,
+  localeEv: CalendarLanguageEv,
+  calendarEv: CalendarEv)
+  extends BinaryCalendarBCDUnparser(e, pattern, localeEv, calendarEv)
+  with PrimUnparser {
+
+  /**
+   * Primitive unparsers must override runtimeDependencies
+   */
+  override lazy val runtimeDependencies = Seq(localeEv, calendarEv)
+
+  def unparse(state: UState): Unit = {
+    doUnparse(state, 0)
+  }
+
+}
diff --git a/daffodil-runtime1-unparser/src/main/scala/org/apache/daffodil/processors/unparsers/ConvertTextCalendarUnparser.scala b/daffodil-runtime1-unparser/src/main/scala/org/apache/daffodil/processors/unparsers/ConvertTextCalendarUnparser.scala
index 16d25f204..77bdd3211 100644
--- a/daffodil-runtime1-unparser/src/main/scala/org/apache/daffodil/processors/unparsers/ConvertTextCalendarUnparser.scala
+++ b/daffodil-runtime1-unparser/src/main/scala/org/apache/daffodil/processors/unparsers/ConvertTextCalendarUnparser.scala
@@ -28,11 +28,11 @@ import org.apache.daffodil.processors.ElementRuntimeData
 import org.apache.daffodil.util.Misc
 import org.apache.daffodil.processors.parsers.ConvertTextCalendarProcessorBase
 
-case class ConvertTextCalendarUnparser(erd: ElementRuntimeData,
+case class ConvertTextCalendarUnparser(context: ElementRuntimeData,
   pattern: String,
   localeEv: CalendarLanguageEv,
   calendarEv: CalendarEv)
-  extends ConvertTextCalendarProcessorBase(erd, pattern)
+  extends ConvertTextCalendarProcessorBase
   with TextPrimUnparser {
 
   /**
diff --git a/daffodil-runtime1/src/main/scala/org/apache/daffodil/processors/PackedBinaryTraits.scala b/daffodil-runtime1/src/main/scala/org/apache/daffodil/processors/PackedBinaryTraits.scala
index 040dbadc3..14fa43ede 100644
--- a/daffodil-runtime1/src/main/scala/org/apache/daffodil/processors/PackedBinaryTraits.scala
+++ b/daffodil-runtime1/src/main/scala/org/apache/daffodil/processors/PackedBinaryTraits.scala
@@ -169,7 +169,7 @@ abstract class PackedBinaryDecimalDelimitedBaseParser(
       } else {
         try {
           val num = toBigDecimal(fieldBytes, binaryDecimalVirtualPoint)
-          state.simpleElement.setDataValue(num)
+          writeResult(state, num)
         } catch {
           case n: NumberFormatException => PE(state, "Error in packed data: \n%s", n.getMessage())
         }
@@ -179,4 +179,8 @@ abstract class PackedBinaryDecimalDelimitedBaseParser(
       return
     }
   }
+
+  def writeResult(state: PState, num: BigDecimal) {
+    state.simpleElement.setDataValue(num)
+  }
 }
diff --git a/daffodil-runtime1/src/main/scala/org/apache/daffodil/processors/parsers/PrimitivesDateTime1.scala b/daffodil-runtime1/src/main/scala/org/apache/daffodil/processors/parsers/PrimitivesDateTime1.scala
index 7ff6b7dee..bcb0bd1e2 100644
--- a/daffodil-runtime1/src/main/scala/org/apache/daffodil/processors/parsers/PrimitivesDateTime1.scala
+++ b/daffodil-runtime1/src/main/scala/org/apache/daffodil/processors/parsers/PrimitivesDateTime1.scala
@@ -17,23 +17,34 @@
 
 package org.apache.daffodil.processors.parsers
 
+import java.lang.{ Long => JLong }
+import java.math.{ BigDecimal => JBigDecimal, BigInteger => JBigInteger }
 import java.text.ParsePosition
 import com.ibm.icu.text.SimpleDateFormat
 import com.ibm.icu.util.Calendar
 import com.ibm.icu.util.ULocale
 import org.apache.daffodil.exceptions.Assert
+
 import org.apache.daffodil.calendar.DFDLDateTime
 import org.apache.daffodil.calendar.DFDLTime
 import org.apache.daffodil.calendar.DFDLDate
 import org.apache.daffodil.processors.CalendarEv
 import org.apache.daffodil.processors.CalendarLanguageEv
 import org.apache.daffodil.processors.ElementRuntimeData
+import org.apache.daffodil.processors.Evaluatable
+import org.apache.daffodil.processors.FieldDFAParseEv
+import org.apache.daffodil.processors.ParseOrUnparseState
 import org.apache.daffodil.processors.Processor
+import org.apache.daffodil.processors.dfa.TextDelimitedParserBase
 import org.apache.daffodil.schema.annotation.props.gen.BinaryCalendarRep
+import org.apache.daffodil.schema.annotation.props.gen.LengthUnits
+import org.apache.daffodil.util.DecimalUtils
+
+trait ConvertTextCalendarProcessorBase extends Processor {
+
+  override val context: ElementRuntimeData
+  val pattern: String
 
-abstract class ConvertTextCalendarProcessorBase(
-  override val context: ElementRuntimeData,
-  pattern: String) extends Processor {
   // The dfdl:calendarLanguage property can be a runtime-valued expression.
   // Hence, locale and calendar, derived from it, can also be runtime-valued.
   //
@@ -82,26 +93,15 @@ abstract class ConvertTextCalendarProcessorBase(
   }
 }
 
-case class ConvertTextCalendarParser(erd: ElementRuntimeData,
-  xsdType: String,
-  prettyType: String,
-  pattern: String,
-  hasTZ: Boolean,
-  localeEv: CalendarLanguageEv,
-  calendarEv: CalendarEv)
-  extends ConvertTextCalendarProcessorBase(erd, pattern)
-  with TextPrimParser {
-
-  override lazy val runtimeDependencies = List(localeEv, calendarEv)
-
-  def parse(start: PState): Unit = {
-    val node = start.simpleElement
-    val str = node.dataValueAsString
-
-    Assert.invariant(str != null)
+trait CalendarParser extends PrimParser with ConvertTextCalendarProcessorBase {
+  def localeEv: CalendarLanguageEv
+  def calendarEv: CalendarEv
+  def xsdType: String
+  def prettyType: String
+  def hasTZ: Boolean
 
+  def writeResult (start: PState, toWrite: String) {
     val pos = new ParsePosition(0)
-
     val locale: ULocale = localeEv.evaluate(start)
     val calendar: Calendar = calendarEv.evaluate(start)
 
@@ -114,13 +114,14 @@ case class ConvertTextCalendarParser(erd: ElementRuntimeData,
 
     val df = tlDataFormatter(locale, calendar)
     val cal = df.getCalendar.clone.asInstanceOf[Calendar]
-    df.parse(str, cal, pos);
+
+    df.parse(toWrite, cal, pos);
 
     // Verify that what was parsed was what was passed exactly in byte count
     // Use pos to verify all characters consumed & check for errors
-    if (pos.getIndex != str.length || pos.getErrorIndex >= 0) {
+    if (pos.getIndex != toWrite.length || pos.getErrorIndex >= 0) {
       val errIndex = if (pos.getErrorIndex >= 0) pos.getErrorIndex else pos.getIndex
-      PE(start, "Convert to %s (for xs:%s): Failed to parse '%s' at character %d.", prettyType, xsdType, str, errIndex + 1)
+      PE(start, "Convert to %s (for xs:%s): Failed to parse '%s' at character %d.", prettyType, xsdType, toWrite, errIndex + 1)
       return
     }
 
@@ -132,7 +133,7 @@ case class ConvertTextCalendarParser(erd: ElementRuntimeData,
       cal.getTime
     } catch {
       case e: IllegalArgumentException => {
-        PE(start, "Convert to %s (for xs:%s): Failed to parse '%s': %s.", prettyType, xsdType, str, e.getMessage())
+        PE(start, "Convert to %s (for xs:%s): Failed to parse '%s': %s.", prettyType, xsdType, toWrite, e.getMessage())
         return
       }
     }
@@ -144,8 +145,28 @@ case class ConvertTextCalendarParser(erd: ElementRuntimeData,
       case _ => Assert.impossibleCase
     }
 
-    node.overwriteDataValue(newCal)
+    start.simpleElement.overwriteDataValue(newCal)
+  }
+}
+
+case class ConvertTextCalendarParser(context: ElementRuntimeData,
+  xsdType: String,
+  prettyType: String,
+  pattern: String,
+  hasTZ: Boolean,
+  localeEv: CalendarLanguageEv,
+  calendarEv: CalendarEv)
+  extends CalendarParser
+  with TextPrimParser {
+
+  override lazy val runtimeDependencies = List(localeEv, calendarEv)
 
+  def parse(start: PState): Unit = {
+    val node = start.simpleElement
+    val str = node.dataValueAsString
+
+    Assert.invariant(str != null)
+    writeResult(start, str)
   }
 }
 
@@ -180,6 +201,8 @@ case class ConvertBinaryCalendarSecMilliParser(
 
   override lazy val runtimeDependencies = Nil
 
+  def toBigDecimal(num: Array[Byte], scale: Int): JBigDecimal = DecimalUtils.bcdToBigDecimal(num, scale)
+
   def parse(start: PState): Unit = {
 
     val dis = start.dataInputStream
@@ -207,3 +230,94 @@ case class ConvertBinaryCalendarSecMilliParser(
     start.simpleElement.overwriteDataValue(newCal)
   }
 }
+
+abstract class BinaryCalendarBCDParser(
+  override val context: ElementRuntimeData,
+  hasTZ: Boolean,
+  pattern: String,
+  localeEv: CalendarLanguageEv,
+  calendarEv: CalendarEv,
+  xsdType: String,
+  prettyType: String)
+  extends CalendarParser {
+
+  def toBigDecimal(num: Array[Byte], scale: Int): JBigDecimal = DecimalUtils.bcdToBigDecimal(num, scale)
+
+  def getBitLength(start: ParseOrUnparseState): Int
+
+  def parse(start: PState): Unit = {
+
+    val dis = start.dataInputStream
+    val nBits = getBitLength(start)
+    if (nBits == 0) return // zero length is used for outputValueCalc often.
+
+    if (!dis.isDefinedForLength(nBits)) {
+      PE(start, "Insufficient bits in data. Needed %d bit(s) but found only %d available.", nBits, dis.remainingBits.get)
+      return
+    }
+
+    try {
+      // Use '0' for the binaryDecimalVirtualPoint because its location will be implied by the pattern
+      val bigDec: BigDecimal = toBigDecimal(dis.getByteArray(nBits, start), 0)
+      writeResult(start, bigDec.toString())
+    } catch {
+      case n: NumberFormatException => PE(start, "Error in packed data: \n%s", n.getMessage())
+    }
+  }
+}
+
+case class BinaryCalendarBCDKnownLengthParser(
+  override val context: ElementRuntimeData,
+  hasTZ: Boolean,
+  lengthInBits: Int,
+  pattern: String,
+  localeEv: CalendarLanguageEv,
+  calendarEv: CalendarEv,
+  xsdType: String,
+  prettyType: String)
+  extends BinaryCalendarBCDParser(context, hasTZ, pattern, localeEv, calendarEv, xsdType, prettyType)
+  with PrimParser
+  with HasKnownLengthInBits {
+
+  override lazy val runtimeDependencies = List(localeEv, calendarEv)
+}
+
+case class BinaryCalendarBCDRuntimeLengthParser(
+  override val e: ElementRuntimeData,
+  hasTZ: Boolean,
+  pattern: String,
+  localeEv: CalendarLanguageEv,
+  calendarEv: CalendarEv,
+  xsdType: String,
+  prettyType: String,
+  val lengthEv: Evaluatable[JLong],
+  val lUnits: LengthUnits)
+  extends BinaryCalendarBCDParser(e, hasTZ, pattern, localeEv, calendarEv, xsdType, prettyType)
+  with PrimParser
+  with HasRuntimeExplicitLength {
+
+  override lazy val runtimeDependencies = List(localeEv, calendarEv, lengthEv)
+}
+
+case class BinaryCalendarBCDDelimitedLengthParser(
+  e: ElementRuntimeData,
+  hasTZ: Boolean,
+  pattern: String,
+  localeEv: CalendarLanguageEv,
+  calendarEv: CalendarEv,
+  xsdType: String,
+  prettyType: String,
+  textParser: TextDelimitedParserBase,
+  fieldDFAEv: FieldDFAParseEv,
+  isDelimRequired: Boolean)
+  extends PackedBinaryDecimalDelimitedBaseParser(e, textParser, fieldDFAEv, isDelimRequired, 0 )
+  with CalendarParser {
+
+  override def toBigInteger(num: Array[Byte]): JBigInteger = DecimalUtils.bcdToBigInteger(num)
+  def toBigDecimal(num: Array[Byte], scale: Int): JBigDecimal = DecimalUtils.bcdToBigDecimal(num, scale)
+
+  override def writeResult(state: PState, num: BigDecimal) {
+    super[CalendarParser].writeResult(state, num.toString())
+  }
+
+}
diff --git a/daffodil-test/src/test/resources/org/apache/daffodil/section05/simple_types/SimpleTypes.tdml b/daffodil-test/src/test/resources/org/apache/daffodil/section05/simple_types/SimpleTypes.tdml
index 8d215cd75..f413ee867 100644
--- a/daffodil-test/src/test/resources/org/apache/daffodil/section05/simple_types/SimpleTypes.tdml
+++ b/daffodil-test/src/test/resources/org/apache/daffodil/section05/simple_types/SimpleTypes.tdml
@@ -263,9 +263,62 @@
       dfdl:binaryCalendarRep="binarySeconds" dfdl:binaryCalendarEpoch="2000-1-1T00:00"/>
     <xs:element name="dateTimeBin11" type="xs:dateTime" dfdl:lengthKind="implicit" dfdl:lengthUnits="bytes"
       dfdl:binaryCalendarRep="binarySeconds" dfdl:binaryCalendarEpoch="01-01-2000T00:00:00"/>
+    <xs:element name="dateTimeBin12" type="xs:dateTime" dfdl:lengthKind="delimited" dfdl:terminator=";"
+      dfdl:binaryCalendarRep="binarySeconds" dfdl:binaryCalendarEpoch="1977-01-01T00:00:07"/>
+
+    <xs:element name="dateBinBCD" type="xs:date" dfdl:calendarPattern="MMddyy" dfdl:calendarPatternKind="explicit"
+      dfdl:lengthKind="explicit" dfdl:length="{ 3 }" dfdl:lengthUnits="bytes" dfdl:binaryCalendarRep="bcd"/>
+    <xs:element name="dateBinBCD2" type="xs:date" dfdl:calendarPattern="MMddyyyy" dfdl:calendarPatternKind="explicit"
+      dfdl:lengthKind="explicit" dfdl:length="{ 4 }" dfdl:lengthUnits="bytes" dfdl:binaryCalendarRep="bcd"/>
+    <xs:element name="dateBinBCD3" type="xs:date" dfdl:calendarPattern="MM-dd-yy" dfdl:calendarPatternKind="explicit"
+      dfdl:lengthKind="explicit" dfdl:length="{ 3 }" dfdl:lengthUnits="bytes" dfdl:binaryCalendarRep="bcd"/>
+    <xs:element name="dateBinBCD4" type="xs:date" dfdl:calendarPattern="MMddyy" dfdl:calendarPatternKind="explicit"
+      dfdl:lengthKind="explicit" dfdl:length="{ 7 }" dfdl:lengthUnits="bits" dfdl:binaryCalendarRep="bcd"/>
+
+    <xs:element name="timeBinBCD" type="xs:time" dfdl:calendarPattern="HHmmss" dfdl:calendarPatternKind="explicit"
+      dfdl:lengthKind="explicit" dfdl:length="{ 3 }" dfdl:lengthUnits="bytes" dfdl:binaryCalendarRep="bcd"/>
+    <xs:element name="timeBinBCD2" type="xs:time" dfdl:calendarPattern="HHmmssSSSS" dfdl:calendarPatternKind="explicit"
+      dfdl:lengthKind="explicit" dfdl:length="{ 5 }" dfdl:lengthUnits="bytes" dfdl:binaryCalendarRep="bcd"/>
+    <xs:element name="timeBinBCD3" type="xs:time" dfdl:calendarPatternKind="implicit"
+      dfdl:lengthKind="explicit" dfdl:length="{ 5 }" dfdl:lengthUnits="bytes" dfdl:binaryCalendarRep="bcd"/>
+    <xs:element name="timeBinBCD4" type="xs:time" dfdl:calendarPattern="HHmmss" dfdl:calendarPatternKind="explicit"
+      dfdl:lengthKind="implicit" dfdl:binaryCalendarRep="bcd"/>
+    <xs:element name="timeBinBCD5" type="xs:time" dfdl:calendarPattern="HHmmss" dfdl:calendarPatternKind="explicit"
+      dfdl:lengthKind="delimited" dfdl:terminator=";" dfdl:binaryCalendarRep="bcd" dfdl:encoding="ISO-8859-1"/>
+
+    <xs:element name="timeBinBCD6">
+      <xs:complexType>
+        <xs:sequence>
+          <xs:element name="length" type="xs:int" dfdl:representation="binary"
+            dfdl:lengthKind="explicit" dfdl:length="{ 1 }" dfdl:lengthUnits="bytes" />
+          <xs:element name="time" type="xs:time" dfdl:calendarPattern="HHmmss" dfdl:calendarPatternKind="explicit"
+            dfdl:lengthKind="explicit" dfdl:length="{ ../ex:length }" dfdl:lengthUnits="bytes" dfdl:binaryCalendarRep="bcd" />
+        </xs:sequence>
+      </xs:complexType>
+    </xs:element>
+
+    <xs:element name="dateTimeBinBCD" type="xs:dateTime" dfdl:calendarPattern="MMddyyyyHHmmss" dfdl:calendarPatternKind="explicit"
+      dfdl:lengthKind="explicit" dfdl:length="{ 7 }" dfdl:lengthUnits="bytes" dfdl:binaryCalendarRep="bcd"/>
+    <xs:element name="dateTimeBinBCD2" type="xs:dateTime" dfdl:calendarPattern="MMddyyyyhhmmss" dfdl:calendarPatternKind="explicit"
+      dfdl:lengthKind="implicit" dfdl:lengthUnits="bytes" dfdl:binaryCalendarRep="bcd"/>
+    <xs:element name="dateTimeBinBCD3" type="xs:dateTime" dfdl:calendarPattern="MMddyyyyhhmmss" dfdl:calendarPatternKind="explicit"
+      dfdl:lengthKind="explicit" dfdl:length="{ 7 }" dfdl:lengthUnits="bytes" dfdl:binaryCalendarRep="bcd"/>
+
+    <xs:element name="dateTimeBinBCD4">
+      <xs:complexType>
+        <xs:sequence>
+          <xs:element name="num1" type="xs:decimal" dfdl:encoding="ISO-8859-1" dfdl:representation="binary" dfdl:binaryNumberRep="bcd"
+            dfdl:lengthKind="delimited" dfdl:terminator=";" dfdl:binaryDecimalVirtualPoint="0"/>
+          <xs:element name="datetime" type="xs:dateTime" dfdl:calendarPattern="MMddyyyyHHmmss" dfdl:encoding="ISO-8859-1"
+            dfdl:calendarPatternKind="explicit" dfdl:binaryCalendarRep="bcd" dfdl:lengthKind="delimited" dfdl:terminator=";"/>
+          <xs:element name="num2" type="xs:decimal" dfdl:encoding="ISO-8859-1" dfdl:representation="binary" dfdl:binaryNumberRep="bcd"
+            dfdl:lengthKind="delimited" dfdl:terminator=";" dfdl:binaryDecimalVirtualPoint="0"/>
+        </xs:sequence>
+      </xs:complexType>
+    </xs:element>
 
-    <xs:element name="dateBin2" type="xs:date" dfdl:lengthKind="explicit" dfdl:length="{ 4 }"
-      dfdl:lengthUnits="bytes" dfdl:binaryCalendarRep="binarySeconds" dfdl:binaryCalendarEpoch="1970-01-01T00:00:00+00:00"/>
+    <xs:element name="dateBinInvalid" type="xs:date" dfdl:calendarPattern="yyyy.MM.dd" dfdl:calendarPatternKind="explicit" dfdl:lengthKind="explicit"
+      dfdl:length="{ 4 }" dfdl:lengthUnits="bytes" dfdl:binaryCalendarRep="binarySeconds" dfdl:binaryCalendarEpoch="1970-01-01T00:00:00+00:00"/>
 
   </tdml:defineSchema>
   
@@ -2251,7 +2304,244 @@
     </tdml:errors>
   </tdml:parserTestCase>
 
-  <tdml:parserTestCase name="dateBin2" root="dateBin2"
+  <tdml:parserTestCase name="dateTimeBin20" root="dateTimeBin12"
+    model="SimpleTypes-binary" description="Section 5 Schema types-dateTime - DFDL-5-016R"
+    roundTrip="false">
+
+    <tdml:document>
+      <tdml:documentPart type="bits">00000000 00000000 00000000 00111101</tdml:documentPart>
+    </tdml:document>
+    <tdml:errors>
+      <tdml:error>Schema Definition Error: Subset lengthKind='delimited' only supported for packed binary formats.</tdml:error>
+    </tdml:errors>
+  </tdml:parserTestCase>
+
+  <tdml:parserTestCase name="dateBinBCD" root="dateBinBCD"
+    model="SimpleTypes-binary" description="Section 5 Schema types-dateTime - DFDL-5-016R"
+    roundTrip="true">
+
+    <tdml:document>
+      <tdml:documentPart type="byte">12 14 23</tdml:documentPart>
+    </tdml:document>
+    <tdml:infoset>
+      <tdml:dfdlInfoset>
+        <dateBinBCD>2023-12-14</dateBinBCD>
+      </tdml:dfdlInfoset>
+    </tdml:infoset>
+  </tdml:parserTestCase>
+
+  <tdml:parserTestCase name="dateBinBCD2" root="dateBinBCD2"
+    model="SimpleTypes-binary" description="Section 5 Schema types-dateTime - DFDL-5-016R"
+    roundTrip="true">
+
+    <tdml:document>
+      <tdml:documentPart type="byte">12 14 20 23</tdml:documentPart>
+    </tdml:document>
+    <tdml:infoset>
+      <tdml:dfdlInfoset>
+        <dateBinBCD2>2023-12-14</dateBinBCD2>
+      </tdml:dfdlInfoset>
+    </tdml:infoset>
+  </tdml:parserTestCase>
+
+  <tdml:parserTestCase name="dateBinBCD3" root="dateBinBCD"
+    model="SimpleTypes-binary" description="Section 5 Schema types-dateTime - DFDL-5-016R"
+    roundTrip="false">
+
+    <tdml:document>
+      <tdml:documentPart type="byte">12 0F 23</tdml:documentPart>
+    </tdml:document>
+    <tdml:errors>
+      <tdml:error>Parse Error</tdml:error>
+      <tdml:error>Invalid low nibble</tdml:error>
+    </tdml:errors>
+  </tdml:parserTestCase>
+
+  <tdml:parserTestCase name="dateBinBCD4" root="dateBinBCD3"
+    model="SimpleTypes-binary" description="Section 5 Schema types-dateTime - DFDL-5-016R"
+    roundTrip="false">
+
+    <tdml:document>
+      <tdml:documentPart type="byte">08 17 48</tdml:documentPart>
+    </tdml:document>
+    <tdml:errors>
+      <tdml:error>Schema Definition Error</tdml:error>
+      <tdml:error>Character '-' not allowed in dfdl:calendarPattern for xs:date with a binaryCalendarRep of 'bcd'</tdml:error>
+    </tdml:errors>
+  </tdml:parserTestCase>
+
+  <tdml:parserTestCase name="dateBinBCD5" root="dateBinBCD4"
+    model="SimpleTypes-binary" description="Section 5 Schema types-dateTime - DFDL-5-016R"
+    roundTrip="false">
+
+    <tdml:document>
+      <tdml:documentPart type="bits">0000000</tdml:documentPart>
+    </tdml:document>
+    <tdml:errors>
+      <tdml:error>Schema Definition Error</tdml:error>
+      <tdml:error>The given length (7 bits) must be a multiple of 4 when using binaryCalendarRep='bcd'</tdml:error>
+    </tdml:errors>
+  </tdml:parserTestCase>
+
+  <tdml:parserTestCase name="dateBinBCD6" root="dateBinBCD"
+    model="SimpleTypes-binary" description="Section 5 Schema types-dateTime - DFDL-5-016R"
+    roundTrip="true">
+
+    <tdml:document>
+      <tdml:documentPart type="bits">0001 0010 0010 0111 1001 1001</tdml:documentPart>
+    </tdml:document>
+    <tdml:infoset>
+      <tdml:dfdlInfoset>
+        <dateBinBCD>1999-12-27</dateBinBCD>
+      </tdml:dfdlInfoset>
+    </tdml:infoset>
+  </tdml:parserTestCase>
+
+  <tdml:parserTestCase name="timeBinBCD" root="timeBinBCD"
+    model="SimpleTypes-binary" description="Section 5 Schema types-dateTime - DFDL-5-016R"
+    roundTrip="true">
+
+    <tdml:document>
+      <tdml:documentPart type="byte">18 56 03</tdml:documentPart>
+    </tdml:document>
+    <tdml:infoset>
+      <tdml:dfdlInfoset>
+        <timeBinBCD>18:56:03.000000</timeBinBCD>
+      </tdml:dfdlInfoset>
+    </tdml:infoset>
+  </tdml:parserTestCase>
+
+  <tdml:parserTestCase name="timeBinBCD2" root="timeBinBCD2"
+    model="SimpleTypes-binary" description="Section 5 Schema types-dateTime - DFDL-5-016R"
+    roundTrip="twoPass">
+
+    <tdml:document>
+      <tdml:documentPart type="byte">01 45 00 99 87</tdml:documentPart>
+    </tdml:document>
+    <tdml:infoset>
+      <tdml:dfdlInfoset>
+        <timeBinBCD2>01:45:00.998000</timeBinBCD2>
+      </tdml:dfdlInfoset>
+    </tdml:infoset>
+  </tdml:parserTestCase>
+
+  <tdml:parserTestCase name="timeBinBCD3" root="timeBinBCD3"
+    model="SimpleTypes-binary" description="Section 5 Schema types-dateTime - DFDL-5-016R"
+    roundTrip="false">
+
+    <tdml:document>
+      <tdml:documentPart type="byte">01 45 00 99 87</tdml:documentPart>
+    </tdml:document>
+    <tdml:errors>
+      <tdml:error>Schema Definition Error</tdml:error>
+      <tdml:error>calendarPatternKind must be 'explicit' when binaryCalendarRep='bcd'</tdml:error>
+    </tdml:errors>
+  </tdml:parserTestCase>
+
+  <tdml:parserTestCase name="timeBinBCD4" root="timeBinBCD4"
+    model="SimpleTypes-binary" description="Section 5 Schema types-dateTime - DFDL-5-016R"
+    roundTrip="true">
+
+    <tdml:document>
+      <tdml:documentPart type="byte">18 56 03</tdml:documentPart>
+    </tdml:document>
+    <tdml:errors>
+      <tdml:error>Schema Definition Error</tdml:error>
+      <tdml:error>Size of binary data 'Time' cannot be determined implicitly</tdml:error>
+    </tdml:errors>
+  </tdml:parserTestCase>
+
+  <tdml:parserTestCase name="timeBinBCD5" root="timeBinBCD5"
+    model="SimpleTypes-binary" description="Section 5 Schema types-dateTime - DFDL-5-016R"
+    roundTrip="true">
+
+    <tdml:document>
+      <tdml:documentPart type="byte">18 56 03 3B</tdml:documentPart>
+    </tdml:document>
+    <tdml:infoset>
+      <tdml:dfdlInfoset>
+        <timeBinBCD5>18:56:03.000000</timeBinBCD5>
+      </tdml:dfdlInfoset>
+    </tdml:infoset>
+  </tdml:parserTestCase>
+
+  <tdml:parserTestCase name="timeBinBCD6" root="timeBinBCD6"
+    model="SimpleTypes-binary" description="Section 5 Schema types-dateTime - DFDL-5-016R"
+    roundTrip="true">
+
+    <tdml:document>
+      <tdml:documentPart type="byte">03 18 56 03</tdml:documentPart>
+    </tdml:document>
+    <tdml:infoset>
+      <tdml:dfdlInfoset>
+        <timeBinBCD6>
+          <length>3</length>
+          <time>18:56:03.000000</time>
+        </timeBinBCD6>
+      </tdml:dfdlInfoset>
+    </tdml:infoset>
+  </tdml:parserTestCase>
+
+  <tdml:parserTestCase name="dateTimeBinBCD" root="dateTimeBinBCD"
+    model="SimpleTypes-binary" description="Section 5 Schema types-dateTime - DFDL-5-016R"
+    roundTrip="true">
+
+    <tdml:document>
+      <tdml:documentPart type="byte">06 14 20 04 18 56 03</tdml:documentPart>
+    </tdml:document>
+    <tdml:infoset>
+      <tdml:dfdlInfoset>
+        <dateTimeBinBCD>2004-06-14T18:56:03.000000</dateTimeBinBCD>
+      </tdml:dfdlInfoset>
+    </tdml:infoset>
+  </tdml:parserTestCase>
+
+  <tdml:parserTestCase name="dateTimeBinBCD2" root="dateTimeBinBCD2"
+    model="SimpleTypes-binary" description="Section 5 Schema types-dateTime - DFDL-5-016R"
+    roundTrip="false">
+
+    <tdml:document>
+      <tdml:documentPart type="byte">01 45 00 99 87</tdml:documentPart>
+    </tdml:document>
+    <tdml:errors>
+      <tdml:error>Schema Definition Error</tdml:error>
+      <tdml:error>Size of binary data 'DateTime' with binaryCalendarRep='bcd' cannot be determined implicitly</tdml:error>
+    </tdml:errors>
+  </tdml:parserTestCase>
+
+  <tdml:parserTestCase name="dateTimeBinBCD3" root="dateTimeBinBCD3"
+    model="SimpleTypes-binary" description="Section 5 Schema types-dateTime - DFDL-5-016R"
+    roundTrip="true">
+
+    <tdml:document>
+      <tdml:documentPart type="byte">06 14 20 04 18 56 03</tdml:documentPart>
+    </tdml:document>
+    <tdml:infoset>
+      <tdml:dfdlInfoset>
+        <dateTimeBinBCD3>2004-06-14T18:56:03.000000</dateTimeBinBCD3>
+      </tdml:dfdlInfoset>
+    </tdml:infoset>
+  </tdml:parserTestCase>
+
+  <tdml:parserTestCase name="dateTimeBinBCD4" root="dateTimeBinBCD4"
+    model="SimpleTypes-binary" description="Section 5 Schema types-dateTime - DFDL-5-016R"
+    roundTrip="true">
+
+    <tdml:document>
+      <tdml:documentPart type="byte">03 3B 06 14 20 04 18 56 03 3B 19 3B</tdml:documentPart>
+    </tdml:document>
+    <tdml:infoset>
+      <tdml:dfdlInfoset>
+        <dateTimeBinBCD4>
+          <num1>3</num1>
+          <datetime>2004-06-14T18:56:03.000000</datetime>
+          <num2>19</num2>
+        </dateTimeBinBCD4>
+      </tdml:dfdlInfoset>
+    </tdml:infoset>
+  </tdml:parserTestCase>
+
+  <tdml:parserTestCase name="dateBinInvalid" root="dateBinInvalid"
     model="SimpleTypes-binary" description="Section 5 Schema types-dateTime - DFDL-5-016R"
     roundTrip="false">
 
diff --git a/daffodil-test/src/test/scala-debug/org/apache/daffodil/section05/simple_types/TestSimpleTypesDebug.scala b/daffodil-test/src/test/scala-debug/org/apache/daffodil/section05/simple_types/TestSimpleTypesDebug.scala
index a2498e1eb..499a13d9d 100644
--- a/daffodil-test/src/test/scala-debug/org/apache/daffodil/section05/simple_types/TestSimpleTypesDebug.scala
+++ b/daffodil-test/src/test/scala-debug/org/apache/daffodil/section05/simple_types/TestSimpleTypesDebug.scala
@@ -117,4 +117,6 @@ class TestSimpleTypesDebug {
 
   // DAFFODIL-1946
   @Test def test_dateTimeImplicitPatternFail5() { runner.runOneTest("dateTimeImplicitPatternFail5") }
+
+  @Test def test_dateTimeBinBCD3() { runner.runOneTest("dateTimeBinBCD3") }
 }
diff --git a/daffodil-test/src/test/scala/org/apache/daffodil/section05/simple_types/TestSimpleTypes.scala b/daffodil-test/src/test/scala/org/apache/daffodil/section05/simple_types/TestSimpleTypes.scala
index a87831393..1957606b9 100644
--- a/daffodil-test/src/test/scala/org/apache/daffodil/section05/simple_types/TestSimpleTypes.scala
+++ b/daffodil-test/src/test/scala/org/apache/daffodil/section05/simple_types/TestSimpleTypes.scala
@@ -189,7 +189,24 @@ class TestSimpleTypes {
   @Test def test_dateTimeBin17() { runner.runOneTest("dateTimeBin17") }
   @Test def test_dateTimeBin18() { runner.runOneTest("dateTimeBin18") }
   @Test def test_dateTimeBin19() { runner.runOneTest("dateTimeBin19") }
-  @Test def test_dateBin2() { runner.runOneTest("dateBin2") }
+  @Test def test_dateTimeBin20() { runner.runOneTest("dateTimeBin20") }
+  @Test def test_dateBinBCD() { runner.runOneTest("dateBinBCD") }
+  @Test def test_dateBinBCD2() { runner.runOneTest("dateBinBCD2") }
+  @Test def test_dateBinBCD3() { runner.runOneTest("dateBinBCD3") }
+  @Test def test_dateBinBCD4() { runner.runOneTest("dateBinBCD4") }
+  @Test def test_dateBinBCD5() { runner.runOneTest("dateBinBCD5") }
+  @Test def test_dateBinBCD6() { runner.runOneTest("dateBinBCD6") }
+  @Test def test_timeBinBCD() { runner.runOneTest("timeBinBCD") }
+  @Test def test_timeBinBCD2() { runner.runOneTest("timeBinBCD2") }
+  @Test def test_timeBinBCD3() { runner.runOneTest("timeBinBCD3") }
+  @Test def test_timeBinBCD4() { runner.runOneTest("timeBinBCD4") }
+  @Test def test_timeBinBCD5() { runner.runOneTest("timeBinBCD5") }
+  @Test def test_timeBinBCD6() { runner.runOneTest("timeBinBCD6") }
+  @Test def test_dateTimeBinBCD() { runner.runOneTest("dateTimeBinBCD") }
+  @Test def test_dateTimeBinBCD2() { runner.runOneTest("dateTimeBinBCD2") }
+  //@Test def test_dateTimeBinBCD3() { runner.runOneTest("dateTimeBinBCD3") }
+  @Test def test_dateTimeBinBCD4() { runner.runOneTest("dateTimeBinBCD4") }
+  @Test def test_dateBinInvalid() { runner.runOneTest("dateBinInvalid") }
 
   @Test def test_dateTimeImplicitPattern() { runner.runOneTest("dateTimeImplicitPattern") }
   @Test def test_dateTimeImplicitPatternFail() { runner.runOneTest("dateTimeImplicitPatternFail") }


 

----------------------------------------------------------------
This is an automated message from the Apache Git Service.
To respond to the message, please log on GitHub and use the
URL above to go to the specific comment.
 
For queries about this service, please contact Infrastructure at:
users@infra.apache.org


With regards,
Apache Git Services