Parse3339

0.6.0

A fast pure Swift RFC 3339 timestamp parser
juri/Parse3339

What's New

0.6.0

2023-08-02T08:32:42Z

Another nanosecond fix: now include correct nanoseconds in the Date value created with the Unix API fast path.

Thanks to @stephencelis for the report.

Build

Parse3339

Parse3339 is a fast RFC 3339 time stamp parser written in pure Swift.

RFC 3339 specifies the commonly used subset of ISO 8601 suitable for time stamps. This parser restricts the subset even further. The following are the formats supported by Parse3339:

  • 2023-07-09T113:14:00+03:00
  • 2023-07-09T113:14:00.2+03:00
  • 2023-07-09T113:14:00Z
  • 2023-07-09T113:14:00.2Z

There's nothing to configure, and it's all in just file in case you want to copy it over instead of using it as a package.

Usage

import Parse3339

let s = "2023-07-09T13:14:00+03:00"
guard let parts = Parse3339.parse(s) else {
    return
}
let date = parts.date
print(date.timeIntervalSinceReferenceDate)
// output: 710590440.0

There's a helper function you can use with Foundation's JSONDecoder:

import Parse3339

let decoder = JSONDecoder()
decoder.dateDecodingStrategy = .custom(Parse3339.parseFromDecoder(_:))

For Package.swift snippets and documentation, visit the Swift Package Index page.

Speed and memory usage

Parse3339 is pleasantly fast and stingy with memory usage. The package has benchmarks:

env PARSE3339_BENCHMARK=1 swift package benchmark --target ParserBenchmarks

It has benchmarks that parse the same string using Foundation's DateFormatter, Foundation's ISO8601DateFormatter, Parse3339 creating a Date with Foundation's DateComponents and Calendar, and Parse3339 creating a Date with standard Unix functions.

Output from one run:

Parse with DateFormatter
╒════════════════════════════╤═════════╤═════════╤═════════╤═════════╤═════════╤═════════╤═════════╤═════════╕
│ Metric                     │      p0 │     p25 │     p50 │     p75 │     p90 │     p99 │    p100 │ Samples │
╞════════════════════════════╪═════════╪═════════╪═════════╪═════════╪═════════╪═════════╪═════════╪═════════╡
│ Malloc (total)             │     275 │     275 │     275 │     275 │     275 │     275 │     279 │  100000 │
├────────────────────────────┼─────────┼─────────┼─────────┼─────────┼─────────┼─────────┼─────────┼─────────┤
│ Memory (resident peak) (M) │      11 │      15 │      19 │      23 │      25 │      27 │      27 │  100000 │
├────────────────────────────┼─────────┼─────────┼─────────┼─────────┼─────────┼─────────┼─────────┼─────────┤
│ Throughput (# / s) (K)     │      17 │      16 │      16 │      16 │      15 │      12 │       1 │  100000 │
├────────────────────────────┼─────────┼─────────┼─────────┼─────────┼─────────┼─────────┼─────────┼─────────┤
│ Time (total CPU) (ns)      │   59084 │   59967 │   60255 │   61887 │   64927 │   82175 │  236750 │  100000 │
├────────────────────────────┼─────────┼─────────┼─────────┼─────────┼─────────┼─────────┼─────────┼─────────┤
│ Time (wall clock) (ns)     │   58500 │   59391 │   59647 │   61279 │   64255 │   83327 │  513167 │  100000 │
╘════════════════════════════╧═════════╧═════════╧═════════╧═════════╧═════════╧═════════╧═════════╧═════════╛

Parse with ISO8601DateFormatter
╒════════════════════════════╤═════════╤═════════╤═════════╤═════════╤═════════╤═════════╤═════════╤═════════╕
│ Metric                     │      p0 │     p25 │     p50 │     p75 │     p90 │     p99 │    p100 │ Samples │
╞════════════════════════════╪═════════╪═════════╪═════════╪═════════╪═════════╪═════════╪═════════╪═════════╡
│ Malloc (total)             │     496 │     496 │     496 │     496 │     496 │     496 │     497 │  100000 │
├────────────────────────────┼─────────┼─────────┼─────────┼─────────┼─────────┼─────────┼─────────┼─────────┤
│ Memory (resident peak) (K) │    9764 │    9781 │    9781 │    9781 │    9781 │    9781 │    9781 │  100000 │
├────────────────────────────┼─────────┼─────────┼─────────┼─────────┼─────────┼─────────┼─────────┼─────────┤
│ Throughput (# / s) (K)     │      11 │      10 │      10 │      10 │      10 │       7 │       0 │  100000 │
├────────────────────────────┼─────────┼─────────┼─────────┼─────────┼─────────┼─────────┼─────────┼─────────┤
│ Time (total CPU) (ns)      │   91375 │   92351 │   92799 │   95551 │   99519 │  123007 │  542458 │  100000 │
├────────────────────────────┼─────────┼─────────┼─────────┼─────────┼─────────┼─────────┼─────────┼─────────┤
│ Time (wall clock) (ns)     │   90792 │   91711 │   92159 │   94911 │   98879 │  127487 │ 3553542 │  100000 │
╘════════════════════════════╧═════════╧═════════╧═════════╧═════════╧═════════╧═════════╧═════════╧═════════╛

Parse with Parse3339 (DateComponents)
╒════════════════════════════╤═════════╤═════════╤═════════╤═════════╤═════════╤═════════╤═════════╤═════════╕
│ Metric                     │      p0 │     p25 │     p50 │     p75 │     p90 │     p99 │    p100 │ Samples │
╞════════════════════════════╪═════════╪═════════╪═════════╪═════════╪═════════╪═════════╪═════════╪═════════╡
│ Malloc (total)             │      64 │      64 │      64 │      64 │      64 │      64 │      67 │  100000 │
├────────────────────────────┼─────────┼─────────┼─────────┼─────────┼─────────┼─────────┼─────────┼─────────┤
│ Memory (resident peak) (M) │       9 │      41 │      73 │     105 │     124 │     136 │     137 │  100000 │
├────────────────────────────┼─────────┼─────────┼─────────┼─────────┼─────────┼─────────┼─────────┼─────────┤
│ Throughput (# / s) (K)     │      43 │      42 │      42 │      41 │      38 │      29 │       4 │  100000 │
├────────────────────────────┼─────────┼─────────┼─────────┼─────────┼─────────┼─────────┼─────────┼─────────┤
│ Time (total CPU) (ns)      │   23416 │   23999 │   24223 │   25007 │   26463 │   34751 │  206791 │  100000 │
├────────────────────────────┼─────────┼─────────┼─────────┼─────────┼─────────┼─────────┼─────────┼─────────┤
│ Time (wall clock) (ns)     │   22833 │   23423 │   23631 │   24383 │   25807 │   34335 │  211458 │  100000 │
╘════════════════════════════╧═════════╧═════════╧═════════╧═════════╧═════════╧═════════╧═════════╧═════════╛

Parse with Parse3339 (Unix time)
╒════════════════════════════╤═════════╤═════════╤═════════╤═════════╤═════════╤═════════╤═════════╤═════════╕
│ Metric                     │      p0 │     p25 │     p50 │     p75 │     p90 │     p99 │    p100 │ Samples │
╞════════════════════════════╪═════════╪═════════╪═════════╪═════════╪═════════╪═════════╪═════════╪═════════╡
│ Malloc (total)             │       0 │       0 │       0 │       0 │       0 │       0 │       0 │  100000 │
├────────────────────────────┼─────────┼─────────┼─────────┼─────────┼─────────┼─────────┼─────────┼─────────┤
│ Memory (resident peak) (K) │    7831 │    7852 │    7864 │    7864 │    7864 │    7864 │    7864 │  100000 │
├────────────────────────────┼─────────┼─────────┼─────────┼─────────┼─────────┼─────────┼─────────┼─────────┤
│ Throughput (# / s) (K)     │     263 │     252 │     247 │     242 │     233 │     183 │      17 │  100000 │
├────────────────────────────┼─────────┼─────────┼─────────┼─────────┼─────────┼─────────┼─────────┼─────────┤
│ Time (total CPU) (ns)      │    4333 │    4503 │    4543 │    4667 │    4875 │    6543 │   48584 │  100000 │
├────────────────────────────┼─────────┼─────────┼─────────┼─────────┼─────────┼─────────┼─────────┼─────────┤
│ Time (wall clock) (ns)     │    3791 │    3959 │    4041 │    4127 │    4291 │    5459 │   56625 │  100000 │
╘════════════════════════════╧═════════╧═════════╧═════════╧═════════╧═════════╧═════════╧═════════╧═════════╛

Description

  • Swift Tools 5.8.0
View More Packages from this Author

Dependencies

Last updated: Wed Apr 24 2024 20:09:42 GMT-0900 (Hawaii-Aleutian Daylight Time)