Skip to content

Differences from ZXing

KiteQR returns exactly what ZXing returns in almost every case. This page lists the places where it does not, and explains why.

Verified parity

Automated tests check these results:

  • Charsets. Every charset table is validated against the JVM's own java.nio.charset codecs. The check encodes across the whole Basic Multilingual Plane, and decodes every one- and two-byte sequence, for all 21 JDK-backed charsets. GB18030's 4-byte sequences, including the supplementary planes, are checked as well. See JvmCharsetParityTest.
  • ECI coverage. A barcode names its character set with an ECI code (Extended Channel Interpretation). All 27 CharacterSetECI entries resolve to a charset, and every alias the JVM accepts resolves in KiteQR as well.

Known deviations

Calendar events use UTC for local-time values

RFC 2445 lets a DTSTART / DTEND be written three ways:

Form Example KiteQR
Date only 20081021 Midnight UTC, same as ZXing
UTC date-time 20081021T123000Z Exact, same as ZXing
Local date-time 20081021T123000 Interpreted as UTC

On the JVM, ZXing resolves the third form against the host's default TimeZone. Common Kotlin has no access to a host timezone, so KiteQR interprets it as UTC instead. A local-time event therefore comes back shifted by the reader's UTC offset.

If you need host-local semantics, read CalendarParsedResult.getStartTimestamp() as a UTC instant and apply the offset yourself. kotlinx-datetime can do this. You can also prefer QR payloads that use the trailing-Z form.

Date rendering is fixed, not locale-aware

CalendarParsedResult.getDisplayResult() renders timestamps as yyyy-MM-dd HH:mm:ss (or yyyy-MM-dd for all-day events). ZXing uses the JVM's locale-aware DateFormat.MEDIUM, which common Kotlin has no equivalent for. The parsed numeric timestamps are unaffected. Only the human-readable string differs. Format it yourself if you need a localized rendering.

The API keeps ZXing's Java accessors

Classes keep ZXing's method names. Use result.getText() and matrix.getWidth(), not result.text or matrix.width. The same holds across the whole API.