-
Notifications
You must be signed in to change notification settings - Fork 48
/
Timestamp.ts
131 lines (120 loc) · 3.75 KB
/
Timestamp.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
import * as ion from "../Ion";
import { Decimal, IonTypes } from "../Ion";
import { Writer } from "../Ion";
import {
FromJsConstructor,
FromJsConstructorBuilder,
} from "./FromJsConstructor";
import { Value } from "./Value";
const _fromJsConstructor: FromJsConstructor = new FromJsConstructorBuilder()
.withClasses(Date, ion.Timestamp)
.build();
/**
* Represents a timestamp[1] value in an Ion stream.
*
* [1] https://amazon-ion.github.io/ion-docs/docs/spec.html#timestamp
*/
export class Timestamp extends Value(
Date,
IonTypes.TIMESTAMP,
_fromJsConstructor
) {
protected _timestamp: ion.Timestamp;
protected _date: Date;
/**
* Constructor.
* @param dateOrTimestamp A `Date` or `Timestamp` to represent as a timestamp.
* @param annotations An optional array of strings to associate with this timestamp.
*/
constructor(
dateOrTimestamp: Date | ion.Timestamp,
annotations: string[] = []
) {
let date: Date;
let timestamp: ion.Timestamp;
if (dateOrTimestamp instanceof Date) {
date = dateOrTimestamp;
timestamp = Timestamp._timestampFromDate(date);
} else {
timestamp = dateOrTimestamp;
date = timestamp.getDate();
}
super(date);
this._date = date;
this._timestamp = timestamp;
this._setAnnotations(annotations);
}
private static _timestampFromDate(date: Date): ion.Timestamp {
const milliseconds =
date.getUTCSeconds() * 1000 + date.getUTCMilliseconds();
const fractionalSeconds = new Decimal(milliseconds, -3);
// `Date` objects do not store a timezone offset. If the offset is requested
// via `.getTimezoneOffset()`, the configured offset of the host computer
// is returned instead of the timezone that was specified when the Date was
// constructed. Since the timezone of the host may or may not be meaningful
// to the user, we store the time in UTC instead. Users wishing to store a
// specific timezone offset on their dom.Timestamp can pass in an ion.Timestamp
// instead of a Date.
return new ion.Timestamp(
0,
date.getUTCFullYear(),
date.getUTCMonth() + 1, // Timestamp expects a range of 1-12
date.getUTCDate(),
date.getUTCHours(),
date.getUTCMinutes(),
fractionalSeconds
);
}
timestampValue(): ion.Timestamp {
return this._timestamp;
}
dateValue(): Date {
return this._date;
}
writeTo(writer: Writer): void {
writer.setAnnotations(this.getAnnotations());
writer.writeTimestamp(this.timestampValue());
}
_valueEquals(
other: any,
options: {
epsilon?: number | null;
ignoreAnnotations?: boolean;
ignoreTimestampPrecision?: boolean;
onlyCompareIon?: boolean;
} = {
epsilon: null,
ignoreAnnotations: false,
ignoreTimestampPrecision: false,
onlyCompareIon: true,
}
): boolean {
let isSupportedType: boolean = false;
let valueToCompare: any = null;
// if the provided value is an ion.dom.Symbol instance.
if (other instanceof Timestamp) {
isSupportedType = true;
valueToCompare = other.timestampValue();
} else if (!options.onlyCompareIon) {
// We will consider other Timestamp-ish types
if (other instanceof ion.Timestamp) {
// expectedValue is a non-DOM Timestamp
isSupportedType = true;
valueToCompare = other;
} else if (other instanceof Date) {
if (this.dateValue().getTime() === other.getTime()) {
return true;
} else {
return false;
}
}
}
if (!isSupportedType) {
return false;
}
if (options.ignoreTimestampPrecision) {
return this.timestampValue().compareTo(valueToCompare) === 0;
}
return this.timestampValue().equals(valueToCompare);
}
}