(timestamp: unknown, withTz: boolean)
| 14 | const FIRST_AD_TIMESTAMP = new Date("0001-01-01T00:00:00Z").getTime(); |
| 15 | |
| 16 | function formatTimestamp(timestamp: unknown, withTz: boolean): string { |
| 17 | let timestampNumber = 0; |
| 18 | if (typeof timestamp === "number") { |
| 19 | timestampNumber = timestamp; |
| 20 | } else if (typeof timestamp === "string") { |
| 21 | timestampNumber = parseInt(timestamp); |
| 22 | if (isNaN(timestampNumber)) { |
| 23 | return timestamp; |
| 24 | } |
| 25 | } else { |
| 26 | return JSON.stringify(timestamp); |
| 27 | } |
| 28 | |
| 29 | // Timestamps are always stored and transmitted in Materialize as UTC. The |
| 30 | // only difference between the `timestamp without timezone` (`withTz = false`) |
| 31 | // and `timestamp with timezone` (`withTz = true`) types is whether the time |
| 32 | // zone indication is included in the format. |
| 33 | // |
| 34 | // A future version of Materialize may allow users to configure the |
| 35 | // `timezone` session parameter, in which case `withTz = true` would need to |
| 36 | // display the timestamp in the configured time zone. However, at present, |
| 37 | // Materialize always uses `utc` is as the value for `timezone`, so we can |
| 38 | // always format the time in UTC. |
| 39 | |
| 40 | let formatted = formatDateInUtc(timestampNumber, "yyyy-MM-dd HH:mm:ss"); |
| 41 | const milliseconds = formatDateInUtc(timestampNumber, "SSS").replace( |
| 42 | /0*$/, |
| 43 | "", |
| 44 | ); |
| 45 | formatted = |
| 46 | milliseconds.length > 0 ? `${formatted}.${milliseconds}` : formatted; |
| 47 | if (withTz) { |
| 48 | // Append UTC timezone |
| 49 | formatted += "+00"; |
| 50 | } |
| 51 | |
| 52 | const isBcDate = timestampNumber < FIRST_AD_TIMESTAMP; |
| 53 | |
| 54 | if (isBcDate) { |
| 55 | formatted += " BC"; |
| 56 | } |
| 57 | return formatted; |
| 58 | } |
| 59 | |
| 60 | /** |
| 61 | * Formats an array for output as psql would. |
no test coverage detected