Merge pull request #682 from cosmos/toSeconds

Add toSeconds/fromSeconds converters
This commit is contained in:
mergify[bot] 2021-02-16 11:18:56 +00:00 committed by GitHub
commit 640d4ba3b1
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 139 additions and 1 deletions

View File

@ -1,10 +1,20 @@
import { ReadonlyDate } from "readonly-date";
import { DateTime, DateWithNanoseconds, fromRfc3339WithNanoseconds, toRfc3339WithNanoseconds } from "./dates";
import {
DateTime,
DateWithNanoseconds,
fromRfc3339WithNanoseconds,
fromSeconds,
toRfc3339WithNanoseconds,
toSeconds,
} from "./dates";
describe("dates", () => {
describe("fromRfc3339WithNanoseconds", () => {
it("works", () => {
expect(fromRfc3339WithNanoseconds("2020-12-15T10:57:26Z").nanoseconds).toEqual(0);
expect(fromRfc3339WithNanoseconds("2020-12-15T10:57:26.7Z").nanoseconds).toEqual(0);
expect(fromRfc3339WithNanoseconds("2020-12-15T10:57:26.77Z").nanoseconds).toEqual(0);
expect(fromRfc3339WithNanoseconds("2020-12-15T10:57:26.778Z").nanoseconds).toEqual(0);
expect(fromRfc3339WithNanoseconds("2020-12-15T10:57:26.7789Z").nanoseconds).toEqual(900000);
expect(fromRfc3339WithNanoseconds("2020-12-15T10:57:26.77809Z").nanoseconds).toEqual(90000);
@ -52,6 +62,107 @@ describe("dates", () => {
});
});
describe("fromSeconds", () => {
it("works", () => {
{
const date = fromSeconds(1608029846);
expect(date).toEqual(fromRfc3339WithNanoseconds("2020-12-15T10:57:26Z"));
}
{
const date = fromSeconds(1608029846, 0);
expect(date).toEqual(fromRfc3339WithNanoseconds("2020-12-15T10:57:26Z"));
}
{
const date = fromSeconds(1608029846, 1);
expect(date).toEqual(fromRfc3339WithNanoseconds("2020-12-15T10:57:26.000000001Z"));
}
{
const date = fromSeconds(1608029846, 10);
expect(date).toEqual(fromRfc3339WithNanoseconds("2020-12-15T10:57:26.000000010Z"));
}
{
const date = fromSeconds(1608029846, 100);
expect(date).toEqual(fromRfc3339WithNanoseconds("2020-12-15T10:57:26.000000100Z"));
}
{
const date = fromSeconds(1608029846, 1000);
expect(date).toEqual(fromRfc3339WithNanoseconds("2020-12-15T10:57:26.000001000Z"));
}
{
const date = fromSeconds(1608029846, 10000);
expect(date).toEqual(fromRfc3339WithNanoseconds("2020-12-15T10:57:26.000010000Z"));
}
{
const date = fromSeconds(1608029846, 100000);
expect(date).toEqual(fromRfc3339WithNanoseconds("2020-12-15T10:57:26.000100000Z"));
}
{
const date = fromSeconds(1608029846, 1000000);
expect(date).toEqual(fromRfc3339WithNanoseconds("2020-12-15T10:57:26.001000000Z"));
}
{
const date = fromSeconds(1608029846, 10000000);
expect(date).toEqual(fromRfc3339WithNanoseconds("2020-12-15T10:57:26.010000000Z"));
}
{
const date = fromSeconds(1608029846, 100000000);
expect(date).toEqual(fromRfc3339WithNanoseconds("2020-12-15T10:57:26.100000000Z"));
}
});
it("throws for nanos out of range", () => {
expect(() => fromSeconds(1608029846, 1000000000)).toThrow();
expect(() => fromSeconds(1608029846, -1)).toThrow();
expect(() => fromSeconds(1608029846, 1.2)).toThrow();
expect(() => fromSeconds(1608029846, NaN)).toThrow();
});
});
describe("toSeconds", () => {
it("works", () => {
{
const date = fromRfc3339WithNanoseconds("2020-12-15T10:57:26Z");
expect(toSeconds(date)).toEqual({ seconds: 1608029846, nanos: 0 });
}
{
const date = fromRfc3339WithNanoseconds("2020-12-15T10:57:26.7Z");
expect(toSeconds(date)).toEqual({ seconds: 1608029846, nanos: 700000000 });
}
{
const date = fromRfc3339WithNanoseconds("2020-12-15T10:57:26.77Z");
expect(toSeconds(date)).toEqual({ seconds: 1608029846, nanos: 770000000 });
}
{
const date = fromRfc3339WithNanoseconds("2020-12-15T10:57:26.778Z");
expect(toSeconds(date)).toEqual({ seconds: 1608029846, nanos: 778000000 });
}
{
const date = fromRfc3339WithNanoseconds("2020-12-15T10:57:26.7789Z");
expect(toSeconds(date)).toEqual({ seconds: 1608029846, nanos: 778900000 });
}
{
const date = fromRfc3339WithNanoseconds("2020-12-15T10:57:26.77809Z");
expect(toSeconds(date)).toEqual({ seconds: 1608029846, nanos: 778090000 });
}
{
const date = fromRfc3339WithNanoseconds("2020-12-15T10:57:26.778009Z");
expect(toSeconds(date)).toEqual({ seconds: 1608029846, nanos: 778009000 });
}
{
const date = fromRfc3339WithNanoseconds("2020-12-15T10:57:26.7780009Z");
expect(toSeconds(date)).toEqual({ seconds: 1608029846, nanos: 778000900 });
}
{
const date = fromRfc3339WithNanoseconds("2020-12-15T10:57:26.77800009Z");
expect(toSeconds(date)).toEqual({ seconds: 1608029846, nanos: 778000090 });
}
{
const date = fromRfc3339WithNanoseconds("2020-12-15T10:57:26.778000009Z");
expect(toSeconds(date)).toEqual({ seconds: 1608029846, nanos: 778000009 });
}
});
});
describe("DateTime", () => {
it("decodes a string", () => {
expect(DateTime.decode("2020-12-15T10:57:26.778Z").nanoseconds).toEqual(0);

View File

@ -1,4 +1,5 @@
import { fromRfc3339 } from "@cosmjs/encoding";
import { Uint32 } from "@cosmjs/math";
import { ReadonlyDate } from "readonly-date";
export interface ReadonlyDateWithNanoseconds extends ReadonlyDate {
@ -25,6 +26,30 @@ export function toRfc3339WithNanoseconds(dateTime: ReadonlyDateWithNanoseconds):
return `${millisecondIso.slice(0, -1)}${nanoseconds.padStart(6, "0")}Z`;
}
export function fromSeconds(seconds: number, nanos = 0): DateWithNanoseconds {
const checkedNanos = new Uint32(nanos).toNumber();
if (checkedNanos > 999_999_999) {
throw new Error("Nano seconds must not exceed 999999999");
}
const out: DateWithNanoseconds = new Date(seconds * 1000 + Math.floor(checkedNanos / 1000000));
out.nanoseconds = checkedNanos % 1000000;
return out;
}
/**
* Calculates the UNIX timestamp in seconds as well as the nanoseconds after the given second.
*
* This is useful when dealing with external systems like the protobuf type
* [.google.protobuf.Timestamp](https://developers.google.com/protocol-buffers/docs/reference/google.protobuf#google.protobuf.Timestamp)
* or any other system that does not use millisecond precision.
*/
export function toSeconds(date: ReadonlyDateWithNanoseconds): { seconds: number; nanos: number } {
return {
seconds: Math.floor(date.getTime() / 1000),
nanos: (date.getTime() % 1000) * 1000000 + (date.nanoseconds ?? 0),
};
}
/** @deprecated Use fromRfc3339WithNanoseconds/toRfc3339WithNanoseconds instead */
export class DateTime {
/** @deprecated Use fromRfc3339WithNanoseconds instead */

View File

@ -5,7 +5,9 @@ export {
DateTime,
ReadonlyDateWithNanoseconds,
fromRfc3339WithNanoseconds,
fromSeconds,
toRfc3339WithNanoseconds,
toSeconds,
} from "./dates";
export {
AbciInfoRequest,