• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

Giorgi / DuckDB.NET / 22729722447

05 Mar 2026 04:48PM UTC coverage: 89.491% (-0.2%) from 89.682%
22729722447

push

github

Giorgi
Use field keyword

1260 of 1467 branches covered (85.89%)

Branch coverage included in aggregate %.

5 of 5 new or added lines in 2 files covered. (100.0%)

12 existing lines in 3 files now uncovered.

2606 of 2853 relevant lines covered (91.34%)

451516.24 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

88.44
/DuckDB.NET.Data/DataChunk/Reader/DateTimeVectorDataReader.cs
1
namespace DuckDB.NET.Data.DataChunk.Reader;
2

3
internal sealed class DateTimeVectorDataReader : VectorDataReaderBase
4
{
5
    private static readonly Type DateTimeType = typeof(DateTime);
3✔
6
    private static readonly Type DateTimeNullableType = typeof(DateTime?);
3✔
7

8
    private static readonly Type DateTimeOffsetType = typeof(DateTimeOffset);
3✔
9
    private static readonly Type DateTimeOffsetNullableType = typeof(DateTimeOffset?);
3✔
10

11
    private static readonly Type DateOnlyType = typeof(DateOnly);
3✔
12
    private static readonly Type DateOnlyNullableType = typeof(DateOnly?);
3✔
13

14
    private static readonly Type TimeOnlyType = typeof(TimeOnly);
3✔
15
    private static readonly Type TimeOnlyNullableType = typeof(TimeOnly?);
3✔
16

17
    internal unsafe DateTimeVectorDataReader(void* dataPointer, ulong* validityMaskPointer, DuckDBType columnType, string columnName) : base(dataPointer, validityMaskPointer, columnType, columnName)
2,322✔
18
    {
19
    }
2,322✔
20

21
    protected override T GetValidValue<T>(ulong offset, Type targetType)
22
    {
23
        if (DuckDBType == DuckDBType.Date)
816✔
24
        {
25
            var (dateOnly, isFinite) = GetDateOnly(offset);
96✔
26

27
            if (!isFinite)
96✔
28
            {
29
                if (targetType == DateTimeType || targetType == DateTimeNullableType)
60✔
30
                {
31
                    ThrowInfinityDateException();
18✔
32
                }
33

34
                if (targetType == DateOnlyType || targetType == DateOnlyNullableType)
42✔
35
                {
36
                    ThrowInfinityDateException();
18✔
37
                }
38

39
                return (T)(object)dateOnly;
24✔
40
            }
41

42
            if (targetType == DateTimeType || targetType == DateTimeNullableType)
36✔
43
            {
44
                var dateTime = (DateTime)dateOnly;
9✔
45
                return (T)(object)dateTime;
9✔
46
            }
47

48
            if (targetType == DateOnlyType || targetType == DateOnlyNullableType)
27✔
49
            {
50
                var dateTime = (DateOnly)dateOnly;
9✔
51
                return (T)(object)dateTime;
9✔
52
            }
53
            return (T)(object)dateOnly;
18✔
54
        }
55

56
        if (DuckDBType == DuckDBType.Time)
720✔
57
        {
58
            var timeOnly = GetTimeOnly(offset);
42✔
59

60
            if (targetType == DateTimeType || targetType == DateTimeNullableType)
42!
61
            {
62
                var dateTime = (DateTime)timeOnly;
×
63
                return (T)(object)dateTime;
×
64
            }
65

66
            if (targetType == TimeOnlyType || targetType == TimeOnlyNullableType)
42✔
67
            {
68
                var dateTime = (TimeOnly)timeOnly;
18✔
69
                return (T)(object)dateTime;
18✔
70
            }
71
            return (T)(object)timeOnly;
24✔
72
        }
73

74
        if (DuckDBType == DuckDBType.TimeTz)
678✔
75
        {
76
            var timeTz = GetTimeTz(offset);
42✔
77

78
            if (targetType == DateTimeOffsetType || targetType == DateTimeOffsetNullableType)
42✔
79
            {
80
                var dateTimeOffset = new DateTimeOffset(timeTz.Time.ToDateTime(), TimeSpan.FromSeconds(timeTz.Offset));
36✔
81
                return (T)(object)dateTimeOffset;
36✔
82
            }
83

84
            return (T)(object)timeTz;
6✔
85
        }
86

87
        return DuckDBType switch
636!
88
        {
636✔
89
            DuckDBType.Timestamp or DuckDBType.TimestampS or
636✔
90
            DuckDBType.TimestampTz or DuckDBType.TimestampMs or
636✔
91
            DuckDBType.TimestampNs => ReadTimestamp<T>(offset, targetType),
636✔
92
            _ => base.GetValidValue<T>(offset, targetType)
×
93
        };
636✔
94
    }
95

96
    private T ReadTimestamp<T>(ulong offset, Type targetType)
97
    {
98
        var timestampStruct = GetFieldData<DuckDBTimestampStruct>(offset);
636✔
99

100
        if (!timestampStruct.IsFinite(DuckDBType))
636✔
101
        {
102
            if (targetType == DateTimeType || targetType == DateTimeNullableType)
246✔
103
            {
104
                ThrowInfinityTimestampException();
90✔
105
            }
106

107
            if (targetType == DateTimeOffsetType || targetType == DateTimeOffsetNullableType)
156✔
108
            {
109
                ThrowInfinityTimestampException();
90✔
110
            }
111

112
            var infinityTimestamp = DuckDBTimestamp.FromDuckDBTimestampStruct(timestampStruct);
66✔
113
            return (T)(object)infinityTimestamp;
66✔
114
        }
115

116
        var (timestamp, additionalTicks) = timestampStruct.ToDuckDBTimestamp(DuckDBType);
390✔
117

118
        if (targetType == DateTimeType || targetType == DateTimeNullableType)
390✔
119
        {
120
            var dateTime = timestamp.ToDateTime().AddTicks(additionalTicks);
192✔
121
            return (T)(object)dateTime;
192✔
122
        }
123

124
        if (targetType == DateTimeOffsetType || targetType == DateTimeOffsetNullableType)
198✔
125
        {
126
            var dateTime = timestamp.ToDateTime().AddTicks(additionalTicks);
171✔
127
            var dateTimeOffset = new DateTimeOffset(dateTime, TimeSpan.Zero);
171✔
128
            return (T)(object)dateTimeOffset;
171✔
129
        }
130

131
        return (T)(object)timestamp;
27✔
132
    }
133

134
    internal override object GetValue(ulong offset, Type targetType)
135
    {
136
        return DuckDBType switch
771,552!
137
        {
771,552✔
138
            DuckDBType.Date => GetDate(offset, targetType),
754,739✔
139
            DuckDBType.Time => GetTime(offset, targetType),
907✔
140
            DuckDBType.TimeTz => GetDateTimeOffset(offset, targetType),
300✔
141
            DuckDBType.Timestamp or DuckDBType.TimestampS or
771,552✔
142
            DuckDBType.TimestampTz or DuckDBType.TimestampMs or
771,552✔
143
            DuckDBType.TimestampNs => GetDateTime(offset, targetType),
15,606✔
144
            _ => base.GetValue(offset, targetType)
×
145
        };
771,552✔
146
    }
147

148
    private DuckDBTimeTz GetTimeTz(ulong offset)
149
    {
150
        var data = GetFieldData<DuckDBTimeTzStruct>(offset);
342✔
151

152
        return NativeMethods.DateTimeHelpers.DuckDBFromTimeTz(data);
342✔
153
    }
154

155
    private DuckDBTimeOnly GetTimeOnly(ulong offset)
156
    {
157
        return NativeMethods.DateTimeHelpers.DuckDBFromTime(GetFieldData<DuckDBTime>(offset));
949✔
158
    }
159

160
    private (DuckDBDateOnly dateOnly, bool IsFinite) GetDateOnly(ulong offset)
161
    {
162
        var date = GetFieldData<DuckDBDate>(offset);
754,835✔
163
        var isFinite = NativeMethods.DateTimeHelpers.DuckDBIsFiniteDate(date);
754,835✔
164
        return (DuckDBDateOnly.FromDuckDBDate(date), isFinite);
754,835✔
165
    }
166

167
    private object GetDate(ulong offset, Type targetType)
168
    {
169
        var (dateOnly, isFinite) = GetDateOnly(offset);
754,739✔
170

171
        if (!isFinite)
754,739✔
172
        {
173
            if (targetType == DateTimeType)
6!
174
            {
UNCOV
175
                ThrowInfinityDateException();
×
176
            }
177

178
            if (targetType == DateOnlyType)
6!
179
            {
UNCOV
180
                ThrowInfinityDateException();
×
181
            }
182

183
            return dateOnly;
6✔
184
        }
185

186
        if (targetType == DateTimeType)
754,733✔
187
        {
188
            return (DateTime)dateOnly;
753,940✔
189
        }
190

191
        if (targetType == DateOnlyType)
793✔
192
        {
193
            return (DateOnly)dateOnly;
459✔
194
        }
195

196
        return dateOnly;
334✔
197
    }
198

199
    private object GetTime(ulong offset, Type targetType)
200
    {
201
        var timeOnly = GetTimeOnly(offset);
907✔
202
        if (targetType == DateTimeType)
907!
203
        {
204
            return (DateTime)timeOnly;
×
205
        }
206

207
        if (targetType == TimeOnlyType)
907✔
208
        {
209
            return (TimeOnly)timeOnly;
640✔
210
        }
211

212
        return timeOnly;
267✔
213
    }
214

215
    private object GetDateTime(ulong offset, Type targetType)
216
    {
217
        var timestampStruct = GetFieldData<DuckDBTimestampStruct>(offset);
15,606✔
218

219
        if (!timestampStruct.IsFinite(DuckDBType))
15,606✔
220
        {
221
            if (targetType == typeof(DateTime))
12!
222
            {
UNCOV
223
                ThrowInfinityTimestampException();
×
224
            }
225

226
            if (targetType == DateTimeOffsetType)
12!
227
            {
UNCOV
228
                ThrowInfinityTimestampException();
×
229
            }
230

231
            return DuckDBTimestamp.FromDuckDBTimestampStruct(timestampStruct);
12✔
232
        }
233

234
        var (timestamp, additionalTicks) = timestampStruct.ToDuckDBTimestamp(DuckDBType);
15,594✔
235

236
        if (targetType == typeof(DateTime))
15,594✔
237
        {
238
            var dateTime = timestamp.ToDateTime().AddTicks(additionalTicks);
15,558✔
239

240
            return dateTime;
15,558✔
241
        }
242

243
        if (targetType == DateTimeOffsetType)
36!
244
        {
245
            var dateTime = timestamp.ToDateTime().AddTicks(additionalTicks);
×
246
            return new DateTimeOffset(dateTime, TimeSpan.Zero);
×
247
        }
248

249
        return timestamp;
36✔
250
    }
251

252
    private object GetDateTimeOffset(ulong offset, Type targetType)
253
    {
254
        var timeTz = GetTimeTz(offset);
300✔
255

256
        if (targetType == typeof(DateTimeOffset))
300✔
257
        {
258
            return new DateTimeOffset(timeTz.Time.ToDateTime(), TimeSpan.FromSeconds(timeTz.Offset));
294✔
259
        }
260

261
        return timeTz;
6✔
262
    }
263

264
    private static void ThrowInfinityDateException()
265
    {
266
        throw new InvalidOperationException(
36✔
267
            "Cannot convert infinite date value to DateTime or DateOnly. " +
36✔
268
            "Use DuckDBDateOnly to read this value and check IsInfinity, IsPositiveInfinity, or IsNegativeInfinity before converting to .NET types.");
36✔
269
    }
270

271
    private static void ThrowInfinityTimestampException()
272
    {
273
        throw new InvalidOperationException(
180✔
274
            "Cannot convert infinite timestamp value to DateTime or DateTimeOffset. " +
180✔
275
            "Use DuckDBTimestamp to read this value and check IsInfinity, IsPositiveInfinity, or IsNegativeInfinity before converting to .NET types.");
180✔
276
    }
277
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc