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

Giorgi / DuckDB.NET / 12205203254

06 Dec 2024 07:50PM UTC coverage: 89.755% (-0.006%) from 89.761%
12205203254

push

github

Giorgi
Refactor DateTime/DuckDBTimestamp conversion

1063 of 1219 branches covered (87.2%)

Branch coverage included in aggregate %.

32 of 32 new or added lines in 4 files covered. (100.0%)

2 existing lines in 1 file now uncovered.

2082 of 2285 relevant lines covered (91.12%)

766705.53 hits per line

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

89.66
/DuckDB.NET.Data/Internal/Reader/DateTimeVectorDataReader.cs
1
using DuckDB.NET.Data.Extensions;
2
using DuckDB.NET.Native;
3
using System;
4

5
namespace DuckDB.NET.Data.Internal.Reader;
6

7
internal sealed class DateTimeVectorDataReader : VectorDataReaderBase
8
{
9
    private static readonly Type DateTimeType = typeof(DateTime);
3✔
10
    private static readonly Type DateTimeNullableType = typeof(DateTime?);
3✔
11

12
    private static readonly Type DateTimeOffsetType = typeof(DateTimeOffset);
3✔
13
    private static readonly Type DateTimeOffsetNullableType = typeof(DateTimeOffset?);
3✔
14

15
#if NET6_0_OR_GREATER
16
    private static readonly Type DateOnlyType = typeof(DateOnly);
3✔
17
    private static readonly Type DateOnlyNullableType = typeof(DateOnly?);
3✔
18

19
    private static readonly Type TimeOnlyType = typeof(TimeOnly);
3✔
20
    private static readonly Type TimeOnlyNullableType = typeof(TimeOnly?);
3✔
21
#endif
22

23
    internal unsafe DateTimeVectorDataReader(void* dataPointer, ulong* validityMaskPointer, DuckDBType columnType, string columnName) : base(dataPointer, validityMaskPointer, columnType, columnName)
2,139✔
24
    {
25
    }
2,139✔
26

27
    protected override T GetValidValue<T>(ulong offset, Type targetType)
28
    {
29
        if (DuckDBType == DuckDBType.Date)
219✔
30
        {
31
            var dateOnly = GetDateOnly(offset);
33✔
32

33
            if (targetType == DateTimeType || targetType == DateTimeNullableType)
33✔
34
            {
35
                var dateTime = (DateTime)dateOnly;
9✔
36
                return (T)(object)dateTime;
9✔
37
            }
38

39
#if NET6_0_OR_GREATER
40
            if (targetType == DateOnlyType || targetType == DateOnlyNullableType)
24✔
41
            {
42
                var dateTime = (DateOnly)dateOnly;
9✔
43
                return (T)(object)dateTime;
9✔
44
            }
45
#endif
46
            return (T)(object)dateOnly;
15✔
47
        }
48

49
        if (DuckDBType == DuckDBType.Time)
186✔
50
        {
51
            var timeOnly = GetTimeOnly(offset);
42✔
52

53
            if (targetType == DateTimeType || targetType == DateTimeNullableType)
42!
54
            {
55
                var dateTime = (DateTime)timeOnly;
×
56
                return (T)(object)dateTime;
×
57
            }
58

59
#if NET6_0_OR_GREATER
60
            if (targetType == TimeOnlyType || targetType == TimeOnlyNullableType)
42✔
61
            {
62
                var dateTime = (TimeOnly)timeOnly;
18✔
63
                return (T)(object)dateTime;
18✔
64
            }
65
#endif
66
            return (T)(object)timeOnly;
24✔
67
        }
68

69
        if (DuckDBType == DuckDBType.TimeTz)
144✔
70
        {
71
            var timeTz = GetTimeTz(offset);
42✔
72

73
            if (targetType == DateTimeOffsetType || targetType == DateTimeOffsetNullableType)
42✔
74
            {
75
                var dateTimeOffset = new DateTimeOffset(timeTz.Time.ToDateTime(), TimeSpan.FromSeconds(timeTz.Offset));
36✔
76
                return (T)(object)dateTimeOffset;
36✔
77
            }
78

79
            return (T)(object)timeTz;
6✔
80
        }
81

82
        return DuckDBType switch
102!
83
        {
102✔
84
            DuckDBType.Timestamp or DuckDBType.TimestampS or 
102✔
85
            DuckDBType.TimestampTz or DuckDBType.TimestampMs or 
102✔
86
            DuckDBType.TimestampNs => ReadTimestamp<T>(offset, targetType),
102✔
UNCOV
87
            _ => base.GetValidValue<T>(offset, targetType)
×
88
        };
102✔
89
    }
90

91
    private T ReadTimestamp<T>(ulong offset, Type targetType)
92
    {
93
        var (timestamp, additionalTicks) = GetFieldData<DuckDBTimestampStruct>(offset).ToDuckDBTimestamp(DuckDBType);
102✔
94

95
        if (targetType == DateTimeType || targetType == DateTimeNullableType)
102✔
96
        {
97
            var dateTime = timestamp.ToDateTime().AddTicks(additionalTicks);
78✔
98
            return (T)(object)dateTime;
78✔
99
        }
100

101
        return (T)(object)timestamp;
24✔
102
    }
103

104
    internal override object GetValue(ulong offset, Type targetType)
105
    {
106
        return DuckDBType switch
769,808!
107
        {
769,808✔
108
            DuckDBType.Date => GetDate(offset, targetType),
752,966✔
109
            DuckDBType.Time => GetTime(offset, targetType),
718✔
110
            DuckDBType.TimeTz => GetDateTimeOffset(offset, targetType),
542✔
111
            DuckDBType.Timestamp or DuckDBType.TimestampS or 
769,808✔
112
            DuckDBType.TimestampTz or DuckDBType.TimestampMs or
769,808✔
113
            DuckDBType.TimestampNs => GetDateTime(offset, targetType),
15,582✔
UNCOV
114
            _ => base.GetValue(offset, targetType)
×
115
        };
769,808✔
116
    }
117

118
    private DuckDBTimeTz GetTimeTz(ulong offset)
119
    {
120
        var data = GetFieldData<DuckDBTimeTzStruct>(offset);
584✔
121

122
        return NativeMethods.DateTimeHelpers.DuckDBFromTimeTz(data);
584✔
123
    }
124

125
    private DuckDBTimeOnly GetTimeOnly(ulong offset)
126
    {
127
        return NativeMethods.DateTimeHelpers.DuckDBFromTime(GetFieldData<DuckDBTime>(offset));
760✔
128
    }
129

130
    private DuckDBDateOnly GetDateOnly(ulong offset)
131
    {
132
        return NativeMethods.DateTimeHelpers.DuckDBFromDate(GetFieldData<DuckDBDate>(offset));
752,999✔
133
    }
134

135
    private object GetDate(ulong offset, Type targetType)
136
    {
137
        var dateOnly = GetDateOnly(offset);
752,966✔
138
        if (targetType == DateTimeType)
752,966✔
139
        {
140
            return (DateTime)dateOnly;
752,229✔
141
        }
142

143
#if NET6_0_OR_GREATER
144
        if (targetType == DateOnlyType)
737✔
145
        {
146
            return (DateOnly)dateOnly;
467✔
147
        }
148
#endif
149

150
        return dateOnly;
270✔
151
    }
152

153
    private object GetTime(ulong offset, Type targetType)
154
    {
155
        var timeOnly = GetTimeOnly(offset);
718✔
156
        if (targetType == DateTimeType)
718!
157
        {
158
            return (DateTime)timeOnly;
×
159
        }
160

161
#if NET6_0_OR_GREATER
162
        if (targetType == TimeOnlyType)
718✔
163
        {
164
            return (TimeOnly)timeOnly;
452✔
165
        }
166
#endif
167

168
        return timeOnly;
266✔
169
    }
170

171
    private object GetDateTime(ulong offset, Type targetType)
172
    {
173
        var (timestamp, additionalTicks) = GetFieldData<DuckDBTimestampStruct>(offset).ToDuckDBTimestamp(DuckDBType);
15,582✔
174

175
        if (targetType == typeof(DateTime))
15,582✔
176
        {
177
            var dateTime = timestamp.ToDateTime().AddTicks(additionalTicks);
15,558✔
178

179
            return dateTime;
15,558✔
180
        }
181

182
        return timestamp;
24✔
183
    }
184

185
    private object GetDateTimeOffset(ulong offset, Type targetType)
186
    {
187
        var timeTz = GetTimeTz(offset);
542✔
188

189
        if (targetType == typeof(DateTimeOffset))
542✔
190
        {
191
            return new DateTimeOffset(timeTz.Time.ToDateTime(), TimeSpan.FromSeconds(timeTz.Offset));
536✔
192
        }
193

194
        return timeTz;
6✔
195
    }
196
}
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