[Cbor] Encoding Arbitrary Time Ratios

Emile Cormier <emile.cormier.jr@gmail.com> Sat, 03 April 2021 01:39 UTC

Return-Path: <emile.cormier.jr@gmail.com>
X-Original-To: cbor@ietfa.amsl.com
Delivered-To: cbor@ietfa.amsl.com
Received: from localhost (localhost []) by ietfa.amsl.com (Postfix) with ESMTP id 06F713A13F4 for <cbor@ietfa.amsl.com>; Fri, 2 Apr 2021 18:39:27 -0700 (PDT)
X-Virus-Scanned: amavisd-new at amsl.com
X-Spam-Flag: NO
X-Spam-Score: -2.097
X-Spam-Status: No, score=-2.097 tagged_above=-999 required=5 tests=[BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, FREEMAIL_FROM=0.001, HTML_MESSAGE=0.001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001, URIBL_BLOCKED=0.001] autolearn=ham autolearn_force=no
Authentication-Results: ietfa.amsl.com (amavisd-new); dkim=pass (2048-bit key) header.d=gmail.com
Received: from mail.ietf.org ([]) by localhost (ietfa.amsl.com []) (amavisd-new, port 10024) with ESMTP id RWs8UGPKAaXR for <cbor@ietfa.amsl.com>; Fri, 2 Apr 2021 18:39:22 -0700 (PDT)
Received: from mail-pf1-x433.google.com (mail-pf1-x433.google.com [IPv6:2607:f8b0:4864:20::433]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by ietfa.amsl.com (Postfix) with ESMTPS id 872123A13F1 for <cbor@ietf.org>; Fri, 2 Apr 2021 18:39:22 -0700 (PDT)
Received: by mail-pf1-x433.google.com with SMTP id x26so4596498pfn.0 for <cbor@ietf.org>; Fri, 02 Apr 2021 18:39:22 -0700 (PDT)
DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=mime-version:from:date:message-id:subject:to; bh=bx6rRaZuuzo6I57O9UhWRzk3WIQBpbiXHQKBP3Oigvo=; b=S9fsymS3mxvrMyt3WpRbUWkr/HzdGspM8yaoTq2QTHVXXbc3Lj6lgWTXEkPtDvjzJx Tfrjyeum4FgxsLLPpODOZTrAvBxAuay6nu6OODduO0rrIZ9my/2KswNMFCCr0mNGgLji AxZj7loAznqrKb+7sCD5BdndEyLS303tRPizBLp+HDw05HqUh7QjdI7oe3AYhC5hfVon eXKvuV+TIXaHL1+r8sS/ZTgrNtQJAqT/vFidCNVF+1/ywulBN5/sVRdrFWRtnuiNnV5+ R6POsea8QqCOLR9b5KchtC+MJ6KgD9AVZwvep6yiQ4CDJQEFEik4mP6RKQpEgc+T4F0f yOPg==
X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:mime-version:from:date:message-id:subject:to; bh=bx6rRaZuuzo6I57O9UhWRzk3WIQBpbiXHQKBP3Oigvo=; b=VeGRqoZ1CrHh5t7avBQJKBOc4OVgFULOsBGJsWlfKzRbNKGctSCXzi0MwX7/M7GedD EI4louNlBMH6cTpb47DIfCeZL7g8HRU5FU6ZBKBeQlNi9FBHjfSU1UwpRorgjncfcqGw 59bMPdKyb1ZTOztOx/qdJQoz5u/WrxCCORMttJI8K9Lnedhel+sM38Dvw6tgGyDmbNGz xJrxJlsL+XRgYek/n/gSirm1AERx0R0aClfG1AgHd4EA6bux97+iiqEH3gABwvsHSobz DQj40UaOEvXXSJpCiGJtDJz2g5FUO6iDbyOnGAtLdPLtj9UW/V0DFS9KsHDA9jWT0gt3 NR7g==
X-Gm-Message-State: AOAM530WjLI8NrfO7rh1ktQ5MpWG5vs/LtrTG6EofwuhFaVpc0vn/pMK xnSWMO0T/aqS3KqcoYWzhuraZb2xWR297GmC0YVDgXU0KyraPA==
X-Google-Smtp-Source: ABdhPJz2U0AjkBz+FEqc7czdySshYKHjyUctla0uooOJaY0ciQxI/9nqekmnHM42vm3GboGBY0RWqQBWQ5wkEyH+AE4=
X-Received: by 2002:a63:fa41:: with SMTP id g1mr5560584pgk.143.1617413961494; Fri, 02 Apr 2021 18:39:21 -0700 (PDT)
MIME-Version: 1.0
From: Emile Cormier <emile.cormier.jr@gmail.com>
Date: Fri, 02 Apr 2021 22:39:10 -0300
Message-ID: <CAM70yxBF2XeewhsXOGv06kTVitz1kNHkYLHGqm3gX0Vyc2c2YA@mail.gmail.com>
To: cbor@ietf.org
Content-Type: multipart/alternative; boundary="000000000000a1366105bf078861"
Archived-At: <https://mailarchive.ietf.org/arch/msg/cbor/PgsVIL__QNDIxyJ7YuOqmtm19IY>
Subject: [Cbor] Encoding Arbitrary Time Ratios
X-BeenThere: cbor@ietf.org
X-Mailman-Version: 2.1.29
Precedence: list
List-Id: "Concise Binary Object Representation \(CBOR\)" <cbor.ietf.org>
List-Unsubscribe: <https://www.ietf.org/mailman/options/cbor>, <mailto:cbor-request@ietf.org?subject=unsubscribe>
List-Archive: <https://mailarchive.ietf.org/arch/browse/cbor/>
List-Post: <mailto:cbor@ietf.org>
List-Help: <mailto:cbor-request@ietf.org?subject=help>
List-Subscribe: <https://www.ietf.org/mailman/listinfo/cbor>, <mailto:cbor-request@ietf.org?subject=subscribe>
X-List-Received-Date: Sat, 03 Apr 2021 01:39:27 -0000

I'd like to be able to encode any arbitrary C++ std::chrono::time_point (
https://en.cppreference.com/w/cpp/chrono/time_point) into CBOR in a
lossless manner. A C++ time_point basically contains three values: a
numerator and denominator to express a ratio in seconds, plus a multiplier
(aka "count"). For example, to store the number of weeks since the epoch,
one could use:

using weeks = std::period<uint64_t, std::ratio<604800, 1>>;
std::chrono::time_point<std::chrono::system_time, weeks> when(123);

In order words, 123 * (604800 / 1) seconds.

I could of course convert 123 weeks to seconds before encoding to CBOR, but
for large numbers of weeks, I would risk arithmetic overflow.

std::ratio<604800, 1> in my example is a compile-time constant, but it
would have to be encoded as a run-time pair of integers over CBOR. Note
that the ratio is arbitrary in C++. Nothing prevents a C++ programmer from
storing a "micro-fortnite" as a std::ratio<14*86400, 1000000>.

To allow the encoding any arbitrary time ratios, I propose a new CBOR tag
wrapping an array of 1 to 3 values:

[Count, Numerator, Denominator]

where Count is an integral or floating point number, and Numerator and
Denominator are integers representing the ratio in seconds.The Numerator
and Denominator would default to 1 if absent.

CBOR tags 1001-1003 would be extended to allow this new CBOR tag as the
value key. This would allow me to encode additional metadata on the
std::chrono::time_point clock type (POSIX, UTC, TAI, GPS).

I can write-up a draft proposal for this new tag on my Github, but I'd like
to hear your thoughts first.

Emile Cormier