(timestampTzValue: RowValue_TimestampTZ)
| 108 | }; |
| 109 | |
| 110 | const formatTimestampWithTz = (timestampTzValue: RowValue_TimestampTZ) => { |
| 111 | const fullDayjs = dayjs( |
| 112 | getDateForPbTimestampProtoEs(timestampTzValue.googleTimestamp) |
| 113 | ) |
| 114 | .utc() |
| 115 | .add(timestampTzValue.offset, "seconds"); |
| 116 | |
| 117 | const hourOffset = Math.floor(timestampTzValue.offset / 60 / 60); |
| 118 | const timezoneOffsetPrefix = Math.abs(hourOffset) < 10 ? "0" : ""; |
| 119 | const timezoneOffset = |
| 120 | hourOffset > 0 |
| 121 | ? `+${timezoneOffsetPrefix}${hourOffset}` |
| 122 | : `-${timezoneOffsetPrefix}${Math.abs(hourOffset)}`; |
| 123 | // Use a local rather than writing back to `timestampTzValue.accuracy`: |
| 124 | // the RowValue comes from the immer-frozen Zustand result set, so an |
| 125 | // in-place assignment throws "Cannot assign to read only property". |
| 126 | const accuracy = |
| 127 | timestampTzValue.accuracy === 0 ? 6 : timestampTzValue.accuracy; |
| 128 | const microseconds = Math.floor( |
| 129 | (timestampTzValue.googleTimestamp?.nanos ?? 0) / Math.pow(10, 9 - accuracy) |
| 130 | ); |
| 131 | const formattedTimestamp = |
| 132 | microseconds > 0 |
| 133 | ? `${fullDayjs.format("YYYY-MM-DD HH:mm:ss")}.${microseconds.toString().padStart(accuracy, "0")}${timezoneOffset}` |
| 134 | : `${fullDayjs.format("YYYY-MM-DD HH:mm:ss")}${timezoneOffset}`; |
| 135 | return formattedTimestamp; |
| 136 | }; |
| 137 | |
| 138 | const escapeMongoDBCollectionName = (name: string) => { |
| 139 | // The backend wraps --eval in single quotes for shell execution and escapes |
no test coverage detected