| /* |
| * Licensed to the Apache Software Foundation (ASF) under one or more |
| * contributor license agreements. See the NOTICE file distributed with |
| * this work for additional information regarding copyright ownership. |
| * The ASF licenses this file to You under the Apache License, Version 2.0 |
| * (the "License"); you may not use this file except in compliance with |
| * the License. You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, software |
| * distributed under the License is distributed on an "AS IS" BASIS, |
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| * See the License for the specific language governing permissions and |
| * limitations under the License. |
| */ |
| |
| namespace Apache.Ignite.Internal.Table; |
| |
| using System; |
| using Ignite.Sql; |
| using NodaTime; |
| |
| /// <summary> |
| /// Temporal type utils. |
| /// </summary> |
| internal static class TemporalTypes |
| { |
| /// <summary> |
| /// Max <see cref="ColumnType.Time"/> type precision. |
| /// </summary> |
| public const int MaxTimePrecision = 9; |
| |
| /// <summary> |
| /// Normalize nanoseconds regarding the precision. |
| /// </summary> |
| /// <param name="nanos">Nanoseconds.</param> |
| /// <param name="precision">Precision.</param> |
| /// <returns>Normalized nanoseconds.</returns> |
| public static int NormalizeNanos(int nanos, int precision) => |
| precision switch |
| { |
| 0 => 0, |
| 1 => (nanos / 100_000_000) * 100_000_000, // 100ms precision. |
| 2 => (nanos / 10_000_000) * 10_000_000, // 10ms precision. |
| 3 => (nanos / 1_000_000) * 1_000_000, // 1ms precision. |
| 4 => (nanos / 100_000) * 100_000, // 100us precision. |
| 5 => (nanos / 10_000) * 10_000, // 10us precision. |
| 6 => (nanos / 1_000) * 1_000, // 1us precision. |
| 7 => (nanos / 100) * 100, // 100ns precision. |
| 8 => (nanos / 10) * 10, // 10ns precision. |
| 9 => nanos, // 1ns precision |
| _ => throw new ArgumentException("Unsupported fractional seconds precision: " + precision) |
| }; |
| |
| /// <summary> |
| /// Deconstructs Instant into seconds and nanoseconds. |
| /// </summary> |
| /// <param name="value">Value.</param> |
| /// <param name="precision">Column precision.</param> |
| /// <returns>Seconds and nanos.</returns> |
| public static (long Seconds, int Nanos) ToSecondsAndNanos(this Instant value, int precision) |
| { |
| // Logic taken from |
| // https://github.com/nodatime/nodatime.serialization/blob/main/src/NodaTime.Serialization.Protobuf/NodaExtensions.cs#L69 |
| // (Apache License). |
| // See discussion: https://github.com/nodatime/nodatime/issues/1644#issuecomment-1260524451 |
| long seconds = value.ToUnixTimeSeconds(); |
| Duration remainder = value - Instant.FromUnixTimeSeconds(seconds); |
| int nanos = NormalizeNanos((int)remainder.NanosecondOfDay, precision); |
| |
| return (seconds, nanos); |
| } |
| } |