98 std::uint32_t dy, std::uint32_t hr,
99 std::uint32_t mn, std::uint32_t se,
101 using Clock =
typename TP::clock;
102 using Duration =
typename TP::duration;
103 DAW_CPP23_STATIC_LOCAL
constexpr auto calc =
111 y -=
static_cast<std::int32_t
>( m ) <= 2;
112 std::int32_t
const era = ( y >= 0 ? y : y - 399 ) / 400;
113 auto const yoe =
static_cast<std::uint32_t
>(
114 static_cast<std::int32_t
>( y ) - era * 400 );
115 auto const doy =
static_cast<std::uint32_t
>(
116 ( 153 * (
static_cast<std::int32_t
>( m ) +
117 (
static_cast<std::int32_t
>( m ) > 2 ? -3 : 9 ) ) +
120 static_cast<std::int32_t
>( d ) - 1 );
121 std::uint32_t
const doe =
122 yoe * 365 + yoe / 4 - yoe / 100 + doy;
123 auto const days_since_epoch =
124 static_cast<int64_t
>( era ) * 146097LL +
125 static_cast<std::int64_t
>( doe ) - 719468LL;
127 using Days = std::chrono::duration<std::int32_t, std::ratio<86400>>;
129 std::chrono::floor<Duration>( std::chrono::nanoseconds( nano ) );
130 return std::chrono::time_point<std::chrono::system_clock,
132 ( Days( days_since_epoch ) + std::chrono::hours( h ) +
133 std::chrono::minutes( min ) +
134 std::chrono::seconds(
static_cast<std::uint32_t
>( s ) ) +
142 auto result = calc( yr, mo, dy, hr, mn, se, ns );
144 if constexpr( std::is_same_v<Clock, std::chrono::system_clock> ) {
147#if defined( __cpp_lib_chrono ) and __cpp_lib_chrono >= 201907
149 auto const match_duration =
150 std::chrono::time_point_cast<Duration>( result );
151 auto const match_clock =
152 std::chrono::clock_cast<Clock>( match_duration );
158 auto const system_epoch = std::chrono::floor<std::chrono::hours>(
159 std::chrono::system_clock::now( ).time_since_epoch( ) +
160 std::chrono::minutes( 30 ) );
161 auto const clock_epoch = std::chrono::floor<std::chrono::hours>(
162 Clock::now( ).time_since_epoch( ) + std::chrono::minutes( 30 ) );
164 DAW_CPP23_STATIC_LOCAL
constexpr auto offset =
165 std::chrono::duration_cast<std::chrono::milliseconds>(
166 clock_epoch - system_epoch );
167 return std::chrono::duration_cast<Duration>( result + offset );
181 result.
day = parse_utils::parse_unsigned<std::uint_least32_t, 2>(
182 std::data( timestamp_str.pop_back( 2U ) ) );
184 ErrorReason::InvalidTimestamp );
185 if( not parse_utils::is_number( timestamp_str.back( ) ) ) {
186 timestamp_str.remove_suffix( );
188 result.month = parse_utils::parse_unsigned<std::uint_least32_t, 2>(
189 std::data( timestamp_str.pop_back( 2U ) ) );
191 ErrorReason::InvalidTimestamp );
192 if( not parse_utils::is_number( timestamp_str.back( ) ) ) {
193 timestamp_str.remove_suffix( );
196 datetime_details::parse_number<std::int_least32_t>( timestamp_str );
210 result.
hour = parse_utils::parse_unsigned<std::uint_least32_t, 2>(
211 std::data( timestamp_str.pop_front( 2 ) ) );
213 if( not parse_utils::is_number( timestamp_str.front( ) ) ) {
214 timestamp_str.remove_prefix( );
216 result.minute = parse_utils::parse_unsigned<std::uint_least32_t, 2>(
217 std::data( timestamp_str.pop_front( 2 ) ) );
219 if( timestamp_str.empty( ) ) {
222 if( not parse_utils::is_number( timestamp_str.front( ) ) ) {
223 timestamp_str.remove_prefix( );
225 result.second = parse_utils::parse_unsigned<std::uint_least32_t, 2>(
226 std::data( timestamp_str.pop_front( 2 ) ) );
228 if( timestamp_str.empty( ) ) {
231 if( not parse_utils::is_number( timestamp_str.front( ) ) ) {
232 timestamp_str.remove_prefix( );
234 auto const nanosecond_str = timestamp_str.substr(
235 0, std::min( timestamp_str.size( ), std::size_t{ 9 } ) );
237 datetime_details::parse_number<std::uint64_t>( nanosecond_str );
238 result.nanosecond *= daw::cxmath::pow10( 9 - timestamp_str.size( ) );
244 DAW_CPP23_STATIC_LOCAL
constexpr daw::string_view t_str =
"T";
245 auto const date_str = ts.pop_front_until( t_str );
248 ErrorReason::InvalidTimestamp );
255 return not( parse_utils::is_number( c ) | ( c ==
':' ) |
260 if( not( ts.empty( ) or ts.front( ) ==
'Z' ) ) {
262 ErrorReason::InvalidTimestamp );
266 switch( ts.front( ) ) {
276 auto hr_offset = parse_utils::parse_unsigned<std::uint_least32_t, 2>(
279 daw::json::ErrorReason::InvalidTimestamp );
280 if( ts.front( ) ==
':' ) {
283 auto mn_offset = parse_utils::parse_unsigned<std::uint_least32_t, 2>(
286 daw::json::ErrorReason::InvalidTimestamp );
290 hms.hour -= hr_offset;
291 hms.minute -= mn_offset;
294 hms.hour += hr_offset;
295 hms.minute += mn_offset;
298 return civil_to_time_point<TP>( ymd.
year,
319 auto dur_from_epoch = tp.time_since_epoch( );
321 std::chrono::duration<std::int_least32_t, std::ratio<86400>>;
322 auto const days_since_epoch =
323 std::chrono::duration_cast<Days>( dur_from_epoch );
324 std::int_least32_t z = days_since_epoch.count( );
326 std::int_least32_t
const era = ( z >= 0 ? z : z - 146096 ) / 146097;
328 static_cast<std::uint_least32_t
>( z - era * 146097 );
329 std::uint_least32_t
const yoe =
330 ( doe - doe / 1460 + doe / 36524 - doe / 146096 ) / 365;
331 std::int_least32_t
const y =
332 static_cast<std::int_least32_t
>( yoe ) + era * 400;
333 std::uint_least32_t
const doy =
334 doe - ( 365 * yoe + yoe / 4 - yoe / 100 );
335 std::uint_least32_t
const mp = ( 5 * doy + 2 ) / 153;
336 std::uint_least32_t
const d = doy - ( 153 * mp + 2 ) / 5 + 1;
337 auto const m =
static_cast<std::uint_least32_t
>(
338 static_cast<std::int_least32_t
>( mp ) +
339 (
static_cast<std::int_least32_t
>( mp ) < 10 ? 3 : -9 ) );
341 dur_from_epoch -= days_since_epoch;
343 std::chrono::duration_cast<std::chrono::hours>( dur_from_epoch );
344 dur_from_epoch -= hrs;
346 std::chrono::duration_cast<std::chrono::minutes>( dur_from_epoch );
347 dur_from_epoch -= min;
349 std::chrono::duration_cast<std::chrono::seconds>( dur_from_epoch );
350 dur_from_epoch -= sec;
351 auto const dur = std::chrono::duration_cast<std::chrono::nanoseconds>(
353 return ymdhms{ y + ( m <= 2 ),
356 static_cast<std::uint_least32_t
>( hrs.count( ) ),
357 static_cast<std::uint_least32_t
>( min.count( ) ),
358 static_cast<std::uint_least32_t
>( sec.count( ) ),
359 static_cast<std::uint64_t
>( dur.count( ) ) };
398 std::chrono::time_point<std::chrono::system_clock, Duration> tp ) {
399 using days = std::chrono::duration<long, std::ratio<86400>>;
401 std::chrono::duration_cast<days>( tp.time_since_epoch( ) ).count( );
402 auto const dow = z >= -4L ? ( z + 4L ) % 7L : ( z + 5L ) % 7L + 6L;
440 switch( datetime_details::month2num( ts ) ) {
441 case datetime_details::month2num(
"Jan" ):
443 case datetime_details::month2num(
"Feb" ):
445 case datetime_details::month2num(
"Mar" ):
447 case datetime_details::month2num(
"Apr" ):
449 case datetime_details::month2num(
"May" ):
451 case datetime_details::month2num(
"Jun" ):
453 case datetime_details::month2num(
"Jul" ):
455 case datetime_details::month2num(
"Aug" ):
457 case datetime_details::month2num(
"Sep" ):
459 case datetime_details::month2num(
"Oct" ):
461 case datetime_details::month2num(
"Nov" ):
463 case datetime_details::month2num(
"Dec" ):