@@ -323,6 +323,109 @@ Date Date::fromDbString(const std::string &datetime)
323
323
static_cast <double >(timezoneOffset ()));
324
324
}
325
325
326
+ Date Date::parseDatetimeTz (const std::string &datetime)
327
+ {
328
+ unsigned int year = {0 }, month = {0 }, day = {0 }, hour = {0 }, minute = {0 },
329
+ second = {0 }, microSecond = {0 };
330
+ int tzSign{0 }, tzOffset{0 };
331
+ std::vector<std::string> v = splitString (datetime, " " );
332
+ if (v.empty ())
333
+ {
334
+ throw std::invalid_argument (" Invalid date string: " + datetime);
335
+ }
336
+
337
+ // parse date
338
+ const std::vector<std::string> date = splitString (v[0 ], " -" );
339
+ if (date.size () != 3 )
340
+ {
341
+ throw std::invalid_argument (" Invalid date string: " + datetime);
342
+ }
343
+ year = std::stol (date[0 ]);
344
+ month = std::stol (date[1 ]);
345
+ day = std::stol (date[2 ]);
346
+
347
+ // only have date part
348
+ if (v.size () <= 1 )
349
+ {
350
+ return trantor::Date{year, month, day};
351
+ }
352
+
353
+ // check timezone without space seperated
354
+ if (v.size () == 2 )
355
+ {
356
+ auto pos = v[1 ].find (' +' );
357
+ if (pos != std::string::npos)
358
+ {
359
+ tzSign = 1 ;
360
+ v.push_back (v[1 ].substr (pos + 1 ));
361
+ v[1 ] = v[1 ].substr (0 , pos);
362
+ }
363
+ else if ((pos = v[1 ].find (' -' )) != std::string::npos)
364
+ {
365
+ tzSign = -1 ;
366
+ v.push_back (v[1 ].substr (pos + 1 ));
367
+ v[1 ] = v[1 ].substr (0 , pos);
368
+ }
369
+ }
370
+
371
+ // parse time
372
+ std::vector<std::string> timeParts = splitString (v[1 ], " :" );
373
+ if (timeParts.size () < 2 || timeParts.size () > 3 )
374
+ {
375
+ throw std::invalid_argument (" Invalid time string: " + datetime);
376
+ }
377
+ hour = std::stol (timeParts[0 ]);
378
+ minute = std::stol (timeParts[1 ]);
379
+ if (timeParts.size () == 3 )
380
+ {
381
+ auto secParts = splitString (timeParts[2 ], " ." );
382
+ second = std::stol (secParts[0 ]);
383
+ // micro seconds
384
+ if (secParts.size () > 1 )
385
+ {
386
+ if (secParts[1 ].length () > 6 )
387
+ {
388
+ secParts[1 ].resize (6 );
389
+ }
390
+ else if (secParts[1 ].length () < 6 )
391
+ {
392
+ secParts[1 ].append (6 - secParts[1 ].length (), ' 0' );
393
+ }
394
+ microSecond = std::stol (secParts[1 ]);
395
+ }
396
+ }
397
+
398
+ // timezone
399
+ if (v.size () >= 3 )
400
+ {
401
+ std::string &tz = v[2 ];
402
+ if (tzSign == 0 )
403
+ {
404
+ if (tz[0 ] == ' -' )
405
+ {
406
+ tz = tz.substr (1 );
407
+ tzSign = -1 ;
408
+ }
409
+ else
410
+ {
411
+ tzSign = 1 ;
412
+ }
413
+ }
414
+
415
+ auto tzParts = splitString (tz, " :" );
416
+ if (tzParts.size () == 1 && tz.size () == 4 )
417
+ {
418
+ tzParts = {tz.substr (0 , 2 ), tz.substr (2 )}; // 0800
419
+ }
420
+ int tzHour = std::stoi (tzParts[0 ]);
421
+ int tzMin = tzParts.size () > 1 ? std::stoi (tzParts[1 ]) : 0 ;
422
+ tzOffset = tzSign * (tzHour * 3600 + tzMin * 60 );
423
+ }
424
+
425
+ return trantor::Date (year, month, day, hour, minute, second, microSecond)
426
+ .after (timezoneOffset () - tzOffset);
427
+ }
428
+
326
429
std::string Date::toCustomFormattedStringLocal (const std::string &fmtStr,
327
430
bool showMicroseconds) const
328
431
{
0 commit comments