🎯 Ejemplos recomendados
Balanced sample collections from various categories for you to explore
Fecha y Hora Windows - Ejemplos C++
Ejemplos completos de fecha y hora en C++ para plataforma Windows incluyendo adquisición, formateo y operaciones de análisis
💻 Adquisición de Hora Actual cpp
🟡 intermediate
⭐⭐
Obtener hora actual del sistema con varios niveles de precisión y consideraciones de zona horaria
⏱️ 20 min
🏷️ cpp, datetime, time acquisition, windows
Prerequisites:
C++ chrono library, Windows API basics, Time concepts
#include <iostream>
#include <chrono>
#include <ctime>
#include <iomanip>
#include <sstream>
#include <string>
#include <windows.h>
#include <vector>
#include <algorithm>
// 1. Basic time acquisition using C++ chrono
void BasicTimeAcquisition() {
std::cout << "=== Basic Time Acquisition ===" << std::endl;
// System clock time (high resolution)
auto now = std::chrono::system_clock::now();
std::time_t currentTime = std::chrono::system_clock::to_time_t(now);
std::cout << "System clock time:" << std::endl;
std::cout << " Raw time_t: " << currentTime << std::endl;
std::cout << " Ctime format: " << std::ctime(¤tTime);
// Convert to tm structure for detailed manipulation
std::tm localTime;
localtime_s(&localTime, ¤tTime);
std::cout << " Local time components:" << std::endl;
std::cout << " Year: " << (localTime.tm_year + 1900) << std::endl;
std::cout << " Month: " << (localTime.tm_mon + 1) << std::endl;
std::cout << " Day: " << localTime.tm_mday << std::endl;
std::cout << " Hour: " << localTime.tm_hour << std::endl;
std::cout << " Minute: " << localTime.tm_min << std::endl;
std::cout << " Second: " << localTime.tm_sec << std::endl;
std::cout << " Day of week: " << localTime.tm_wday << " (0=Sunday)" << std::endl;
std::cout << " Day of year: " << localTime.tm_yday << std::endl;
std::cout << " Daylight saving: " << (localTime.tm_isdst > 0 ? "Yes" : "No") << std::endl;
// UTC time
std::tm utcTime;
gmtime_s(&utcTime, ¤tTime);
std::cout << " UTC time components:" << std::endl;
std::cout << " Hour: " << utcTime.tm_hour << std::endl;
std::cout << " Minute: " << utcTime.tm_min << std::endl;
std::cout << " Second: " << utcTime.tm_sec << std::endl;
}
// 2. High-precision time measurement
void HighPrecisionTime() {
std::cout << "\n=== High-Precision Time Measurement ===" << std::endl;
// Steady clock (monotonic, suitable for measuring intervals)
auto steadyStart = std::chrono::steady_clock::now();
// Simulate some work
std::vector<int> numbers;
for (int i = 0; i < 1000000; i++) {
numbers.push_back(i * i);
}
std::sort(numbers.begin(), numbers.end());
auto steadyEnd = std::chrono::steady_clock::now();
auto steadyDuration = std::chrono::duration_cast<std::chrono::microseconds>(steadyEnd - steadyStart);
std::cout << "Work completed in: " << steadyDuration.count() << " microseconds" << std::endl;
// High resolution clock
auto highResStart = std::chrono::high_resolution_clock::now();
// Another work simulation
volatile long long sum = 0;
for (int i = 0; i < 10000000; i++) {
sum += i;
}
auto highResEnd = std::chrono::high_resolution_clock::now();
auto highResDuration = std::chrono::duration_cast<std::chrono::nanoseconds>(highResEnd - highResStart);
std::cout << "Calculation completed in: " << highResDuration.count() << " nanoseconds" << std::endl;
// Time conversions
auto milliseconds = std::chrono::duration_cast<std::chrono::milliseconds>(highResDuration);
auto seconds = std::chrono::duration_cast<std::chrono::seconds>(highResDuration);
std::cout << "Time conversions:" << std::endl;
std::cout << " Nanoseconds: " << highResDuration.count() << std::endl;
std::cout << " Microseconds: " << std::chrono::duration_cast<std::chrono::microseconds>(highResDuration).count() << std::endl;
std::cout << " Milliseconds: " << milliseconds.count() << std::endl;
std::cout << " Seconds: " << seconds.count() << std::endl;
}
// 3. Windows-specific time functions
void WindowsTimeFunctions() {
std::cout << "\n=== Windows-Specific Time Functions ===" << std::endl;
// GetSystemTime (UTC time)
SYSTEMTIME systemTime;
GetSystemTime(&systemTime);
std::cout << "GetSystemTime (UTC):" << std::endl;
std::cout << " Year: " << systemTime.wYear << std::endl;
std::cout << " Month: " << systemTime.wMonth << std::endl;
std::cout << " Day: " << systemTime.wDay << std::endl;
std::cout << " Hour: " << systemTime.wHour << std::endl;
std::cout << " Minute: " << systemTime.wMinute << std::endl;
std::cout << " Second: " << systemTime.wSecond << std::endl;
std::cout << " Milliseconds: " << systemTime.wMilliseconds << std::endl;
std::cout << " Day of week: " << systemTime.wDayOfWeek << " (0=Sunday)" << std::endl;
// GetLocalTime (local time)
SYSTEMTIME localTime;
GetLocalTime(&localTime);
std::cout << "\nGetLocalTime (Local):" << std::endl;
std::cout << " Year: " << localTime.wYear << std::endl;
std::cout << " Month: " << localTime.wMonth << std::endl;
std::cout << " Day: " << localTime.wDay << std::endl;
std::cout << " Hour: " << localTime.wHour << std::endl;
std::cout << " Minute: " << localTime.wMinute << std::endl;
std::cout << " Second: " << localTime.wSecond << std::endl;
std::cout << " Milliseconds: " << localTime.wMilliseconds << std::endl;
// GetTickCount (time since system start)
DWORD tickCount = GetTickCount();
std::cout << "\nSystem uptime (GetTickCount): " << tickCount << " milliseconds ("
<< (tickCount / 1000.0 / 3600.0) << " hours)" << std::endl;
// GetTickCount64 for systems that support it
ULONGLONG tickCount64 = GetTickCount64();
std::cout << "System uptime (GetTickCount64): " << tickCount64 << " milliseconds ("
<< (tickCount64 / 1000.0 / 3600.0) << " hours)" << std::endl;
// File time
FILETIME fileTime;
GetSystemTimeAsFileTime(&fileTime);
ULARGE_INTEGER uli;
uli.LowPart = fileTime.dwLowDateTime;
uli.HighPart = fileTime.dwHighDateTime;
std::cout << "\nFile time (100-nanosecond intervals since January 1, 1601):" << std::endl;
std::cout << " Value: " << uli.QuadPart << std::endl;
// Convert file time to system time
SYSTEMTIME fileSystemTime;
FileTimeToSystemTime(&fileTime, &fileSystemTime);
std::cout << " Converted to system time: "
<< fileSystemTime.wYear << "-" << fileSystemTime.wMonth << "-" << fileSystemTime.wDay << " "
<< fileSystemTime.wHour << ":" << fileSystemTime.wMinute << ":" << fileSystemTime.wSecond
<< "." << fileSystemTime.wMilliseconds << std::endl;
}
// 4. Performance counter functions
void PerformanceCounterTime() {
std::cout << "\n=== Performance Counter Time ===" << std::endl;
LARGE_INTEGER frequency;
QueryPerformanceFrequency(&frequency);
LARGE_INTEGER startCount, endCount;
QueryPerformanceCounter(&startCount);
// Simulate some work
volatile double result = 0.0;
for (int i = 0; i < 10000000; i++) {
result += sin(i * 0.001);
}
QueryPerformanceCounter(&endCount);
double elapsedSeconds = static_cast<double>(endCount.QuadPart - startCount.QuadPart) / frequency.QuadPart;
double elapsedMicroseconds = elapsedSeconds * 1000000.0;
std::cout << "Performance counter timing:" << std::endl;
std::cout << " Frequency: " << frequency.QuadPart << " counts per second" << std::endl;
std::cout << " Start count: " << startCount.QuadPart << std::endl;
std::cout << " End count: " << endCount.QuadPart << std::endl;
std::cout << " Elapsed time: " << elapsedSeconds << " seconds" << std::endl;
std::cout << " Elapsed time: " << elapsedMicroseconds << " microseconds" << std::endl;
std::cout << " Calculation result: " << result << std::endl;
}
// 5. Time zone information
void TimeZoneInformation() {
std::cout << "\n=== Time Zone Information ===" << std::endl;
TIME_ZONE_INFORMATION timeZoneInfo;
DWORD result = GetTimeZoneInformation(&timeZoneInfo);
std::cout << "Time zone information:" << std::endl;
std::cout << " Bias from UTC: " << timeZoneInfo.Bias << " minutes" << std::endl;
// Convert bias to hours and minutes
int hours = abs(timeZoneInfo.Bias) / 60;
int minutes = abs(timeZoneInfo.Bias) % 60;
char sign = timeZoneInfo.Bias <= 0 ? '+' : '-';
std::cout << " UTC offset: " << sign << std::setw(2) << std::setfill('0') << hours
<< ":" << std::setw(2) << minutes << std::setfill(' ') << std::endl;
// Standard time
std::cout << "\nStandard time:" << std::endl;
std::wcout << L" Name: " << timeZoneInfo.StandardName << std::endl;
std::cout << " Bias: " << timeZoneInfo.StandardBias << " minutes" << std::endl;
std::cout << " Date: " << timeZoneInfo.StandardDate.wMonth << "/"
<< timeZoneInfo.StandardDate.wDay << " at "
<< timeZoneInfo.StandardDate.wHour << ":"
<< timeZoneInfo.StandardDate.wMinute << std::endl;
// Daylight time
std::cout << "\nDaylight saving time:" << std::endl;
std::wcout << L" Name: " << timeZoneInfo.DaylightName << std::endl;
std::cout << " Bias: " << timeZoneInfo.DaylightBias << " minutes" << std::endl;
std::cout << " Date: " << timeZoneInfo.DaylightDate.wMonth << "/"
<< timeZoneInfo.DaylightDate.wDay << " at "
<< timeZoneInfo.DaylightDate.wHour << ":"
<< timeZoneInfo.DaylightDate.wMinute << std::endl;
// Current time zone status
switch (result) {
case TIME_ZONE_ID_STANDARD:
std::cout << "\nCurrent status: Standard time" << std::endl;
break;
case TIME_ZONE_ID_DAYLIGHT:
std::cout << "\nCurrent status: Daylight saving time" << std::endl;
break;
case TIME_ZONE_ID_UNKNOWN:
std::cout << "\nCurrent status: Unknown" << std::endl;
break;
default:
std::cout << "\nCurrent status: Error (" << result << ")" << std::endl;
break;
}
}
// 6. Timer and alarm functions
void TimerAndAlarm() {
std::cout << "\n=== Timer and Alarm Functions ===" << std::endl;
// Create a timer queue
HANDLE hTimerQueue = CreateTimerQueue();
if (hTimerQueue == NULL) {
std::cout << "Failed to create timer queue" << std::endl;
return;
}
// Timer callback function would be defined elsewhere
// For demonstration, we'll show the setup
HANDLE hTimer;
std::cout << "Timer queue created successfully" << std::endl;
// In a real application, you would create a timer like this:
/*
if (CreateTimerQueueTimer(&hTimer, hTimerQueue,
(WAITORTIMERCALLBACK)TimerCallback,
NULL, 1000, 2000, 0)) {
std::cout << "Timer created successfully" << std::endl;
} else {
std::cout << "Failed to create timer" << std::endl;
}
*/
// Sleep for demonstration
std::cout << "Sleeping for 2 seconds..." << std::endl;
Sleep(2000);
std::cout << "Sleep completed" << std::endl;
// Cleanup
if (hTimerQueue) {
DeleteTimerQueueEx(hTimerQueue, NULL);
std::cout << "Timer queue deleted" << std::endl;
}
// Alternative: Use Waitable Timer
HANDLE hWaitableTimer = CreateWaitableTimer(NULL, FALSE, NULL);
if (hWaitableTimer) {
std::cout << "Waitable timer created" << std::endl;
// Set timer to fire after 1 second
LARGE_INTEGER dueTime;
dueTime.QuadPart = -10000000LL; // 1 second in 100-nanosecond intervals (negative = relative)
if (SetWaitableTimer(hWaitableTimer, &dueTime, 0, NULL, NULL, FALSE)) {
std::cout << "Timer set to fire in 1 second" << std::endl;
// Wait for timer
if (WaitForSingleObject(hWaitableTimer, 2000) == WAIT_OBJECT_0) {
std::cout << "Timer fired!" << std::endl;
} else {
std::cout << "Timer wait timeout" << std::endl;
}
}
CloseHandle(hWaitableTimer);
}
}
// 7. Time measurement utility class
class TimeMeasure {
private:
std::chrono::high_resolution_clock::time_point startTime;
std::string operationName;
public:
TimeMeasure(const std::string& name) : operationName(name) {
startTime = std::chrono::high_resolution_clock::now();
std::cout << "Starting measurement: " << operationName << std::endl;
}
~TimeMeasure() {
auto endTime = std::chrono::high_resolution_clock::now();
auto duration = std::chrono::duration_cast<std::chrono::microseconds>(endTime - startTime);
std::cout << "Completed: " << operationName << " - "
<< duration.count() << " microseconds" << std::endl;
}
// Get elapsed time without destroying the object
double getElapsedMicroseconds() const {
auto currentTime = std::chrono::high_resolution_clock::now();
auto duration = std::chrono::duration_cast<std::chrono::microseconds>(currentTime - startTime);
return static_cast<double>(duration.count());
}
double getElapsedMilliseconds() const {
return getElapsedMicroseconds() / 1000.0;
}
double getElapsedSeconds() const {
return getElapsedMicroseconds() / 1000000.0;
}
};
void demonstrateTimeMeasurement() {
std::cout << "\n=== Time Measurement Utility ===" << std::endl;
// Example 1: Automatic measurement with destructor
{
TimeMeasure measure("Vector operations");
std::vector<int> vec;
for (int i = 0; i < 100000; i++) {
vec.push_back(i);
}
std::sort(vec.begin(), vec.end());
std::reverse(vec.begin(), vec.end());
}
// Example 2: Manual timing
TimeMeasure measure("Loop operations");
for (int i = 0; i < 50000000; i++) {
volatile int x = i * i + i;
(void)x; // Suppress unused variable warning
}
std::cout << "Manual check - elapsed: " << measure.getElapsedMilliseconds() << " ms" << std::endl;
}
// 8. Multiple time format comparison
void compareTimeFormats() {
std::cout << "\n=== Multiple Time Format Comparison ===" << std::endl;
auto now = std::chrono::system_clock::now();
std::time_t currentTime = std::chrono::system_clock::to_time_t(now);
// Format 1: ISO 8601
std::tm utcTime;
gmtime_s(&utcTime, ¤tTime);
std::ostringstream isoStream;
isoStream << std::put_time(&utcTime, "%Y-%m-%dT%H:%M:%SZ");
std::string isoFormat = isoStream.str();
std::cout << "ISO 8601 format: " << isoFormat << std::endl;
// Format 2: RFC 2822
std::ostringstream rfcStream;
rfcStream << std::put_time(&utcTime, "%a, %d %b %Y %H:%M:%S GMT");
std::string rfcFormat = rfcStream.str();
std::cout << "RFC 2822 format: " << rfcFormat << std::endl;
// Format 3: Local time with milliseconds
std::tm localTime;
localtime_s(&localTime, ¤tTime);
// Get milliseconds
auto timeMs = std::chrono::time_point_cast<std::chrono::milliseconds>(now);
auto epochMs = timeMs.time_since_epoch().count();
auto epochSec = currentTime;
int milliseconds = static_cast<int>(epochMs % 1000);
std::ostringstream localStream;
localStream << std::put_time(&localTime, "%Y-%m-%d %H:%M:%S")
<< "." << std::setfill('0') << std::setw(3) << milliseconds;
std::string localFormat = localStream.str();
std::cout << "Local format: " << localFormat << std::endl;
// Format 4: Simple readable format
std::ostringstream readableStream;
readableStream << std::put_time(&localTime, "%B %d, %Y at %I:%M:%S %p");
std::string readableFormat = readableStream.str();
std::cout << "Readable format: " << readableFormat << std::endl;
// Format 5: Compact numeric format
std::ostringstream compactStream;
compactStream << std::put_time(&localTime, "%Y%m%d_%H%M%S");
std::string compactFormat = compactStream.str();
std::cout << "Compact format: " << compactFormat << std::endl;
// Windows SYSTEMTIME to string
SYSTEMTIME systemTime;
GetLocalTime(&systemTime);
std::ostringstream windowsStream;
windowsStream << systemTime.wYear << "-"
<< std::setfill('0') << std::setw(2) << systemTime.wMonth << "-"
<< std::setfill('0') << std::setw(2) << systemTime.wDay << " "
<< std::setfill('0') << std::setw(2) << systemTime.wHour << ":"
<< std::setfill('0') << std::setw(2) << systemTime.wMinute << ":"
<< std::setfill('0') << std::setw(2) << systemTime.wSecond << "."
<< std::setfill('0') << std::setw(3) << systemTime.wMilliseconds;
std::string windowsFormat = windowsStream.str();
std::cout << "Windows format: " << windowsFormat << std::endl;
}
// 9. Time calculation and arithmetic
void timeCalculations() {
std::cout << "\n=== Time Calculations and Arithmetic ===" << std::endl;
// Current time
auto now = std::chrono::system_clock::now();
std::time_t currentTime = std::chrono::system_clock::to_time_t(now);
std::cout << "Current time: " << std::ctime(¤tTime);
// Add 24 hours
auto tomorrow = now + std::chrono::hours(24);
std::time_t tomorrowTime = std::chrono::system_clock::to_time_t(tomorrow);
std::cout << "Tomorrow (24 hours later): " << std::ctime(&tomorrowTime);
// Subtract 7 days
auto weekAgo = now - std::chrono::hours(24 * 7);
std::time_t weekAgoTime = std::chrono::system_clock::to_time_t(weekAgo);
std::cout << "A week ago: " << std::ctime(&weekAgoTime);
// Add 1 hour and 30 minutes
auto future = now + std::chrono::hours(1) + std::chrono::minutes(30);
std::time_t futureTime = std::chrono::system_clock::to_time_t(future);
std::cout << "1 hour 30 minutes later: " << std::ctime(&futureTime);
// Calculate difference between times
auto startTime = now - std::chrono::hours(2);
auto endTime = now + std::chrono::hours(3);
auto duration = endTime - startTime;
auto hours = std::chrono::duration_cast<std::chrono::hours>(duration);
auto minutes = std::chrono::duration_cast<std::chrono::minutes>(duration - hours);
std::cout << "Duration between times: " << hours.count() << " hours, "
<< minutes.count() << " minutes" << std::endl;
// Calculate time of day (seconds since midnight)
std::tm localTime;
localtime_s(&localTime, ¤tTime);
int secondsSinceMidnight = localTime.tm_hour * 3600 +
localTime.tm_min * 60 +
localTime.tm_sec;
std::cout << "Seconds since midnight: " << secondsSinceMidnight << std::endl;
std::cout << "Time remaining until midnight: " << (24 * 3600 - secondsSinceMidnight) << " seconds" << std::endl;
// Calculate week number
char weekBuffer[10];
strftime(weekBuffer, sizeof(weekBuffer), "%U", &localTime);
int weekNumber = std::atoi(weekBuffer);
std::cout << "Week number of year: " << weekNumber << std::endl;
// Calculate day of year
std::cout << "Day of year: " << (localTime.tm_yday + 1) << std::endl;
}
int main() {
std::cout << "=== C++ Windows Date and Time - Time Acquisition ===" << std::endl;
std::cout << "Demonstrating comprehensive time acquisition techniques\n" << std::endl;
try {
// Run all time acquisition examples
BasicTimeAcquisition();
HighPrecisionTime();
WindowsTimeFunctions();
PerformanceCounterTime();
TimeZoneInformation();
TimerAndAlarm();
demonstrateTimeMeasurement();
compareTimeFormats();
timeCalculations();
std::cout << "\nAll time acquisition examples completed successfully!" << std::endl;
} catch (const std::exception& e) {
std::cerr << "Unexpected error: " << e.what() << std::endl;
return 1;
}
return 0;
}
💻 Formateo y Visualización de Hora cpp
🟡 intermediate
⭐⭐⭐
Convertir objetos de tiempo a varios formatos de cadena con opciones de localización y formateo personalizado
⏱️ 25 min
🏷️ cpp, datetime, formatting, windows
Prerequisites:
C++ iomanip, Time patterns, Locale concepts, Windows API
#include <iostream>
#include <chrono>
#include <ctime>
#include <iomanip>
#include <sstream>
#include <string>
#include <vector>
#include <map>
#include <windows.h>
#include <locale>
// 1. Basic time formatting
void BasicTimeFormatting() {
std::cout << "=== Basic Time Formatting ===" << std::endl;
auto now = std::chrono::system_clock::now();
std::time_t currentTime = std::chrono::system_clock::to_time_t(now);
// Local time structure
std::tm localTime;
localtime_s(&localTime, ¤tTime);
std::cout << "Basic formatting using put_time:" << std::endl;
// ISO 8601 format
std::ostringstream isoStream;
isoStream << std::put_time(&localTime, "%Y-%m-%dT%H:%M:%S");
std::cout << "ISO 8601: " << isoStream.str() << std::endl;
// US format
std::ostringstream usStream;
usStream << std::put_time(&localTime, "%m/%d/%Y %I:%M:%S %p");
std::cout << "US format: " << usStream.str() << std::endl;
// European format
std::ostringstream euStream;
euStream << std::put_time(&localTime, "%d.%m.%Y %H:%M:%S");
std::cout << "European format: " << euStream.str() << std::endl;
// Readable format
std::ostringstream readableStream;
readableStream << std::put_time(&localTime, "%A, %B %d, %Y");
std::cout << "Readable: " << readableStream.str() << std::endl;
// Short date
std::ostringstream shortStream;
shortStream << std::put_time(&localTime, "%x");
std::cout << "Short date: " << shortStream.str() << std::endl;
// Long date
std::ostringstream longStream;
longStream << std::put_time(&localTime, "%c");
std::cout << "Long date: " << longStream.str() << std::endl;
// Time only
std::ostringstream timeOnlyStream;
timeOnlyStream << std::put_time(&localTime, "%X");
std::cout << "Time only: " << timeOnlyStream.str() << std::endl;
// Custom format
std::ostringstream customStream;
customStream << std::put_time(&localTime, "Year: %Y, Week: %U, Day: %j");
std::cout << "Custom: " << customStream.str() << std::endl;
}
// 2. Advanced formatting with milliseconds and microseconds
void HighResolutionFormatting() {
std::cout << "\n=== High-Resolution Formatting ===" << std::endl;
auto now = std::chrono::system_clock::now();
auto timeMs = std::chrono::time_point_cast<std::chrono::milliseconds>(now);
auto timeUs = std::chrono::time_point_cast<std::chrono::microseconds>(now);
std::time_t currentTime = std::chrono::system_clock::to_time_t(now);
std::tm localTime;
localtime_s(&localTime, ¤tTime);
// Get milliseconds and microseconds
auto epochMs = timeMs.time_since_epoch().count();
auto epochUs = timeUs.time_since_epoch().count();
auto epochSec = currentTime;
int milliseconds = static_cast<int>(epochMs % 1000);
int microseconds = static_cast<int>(epochUs % 1000000);
std::cout << "High-resolution formatting:" << std::endl;
// With milliseconds
std::ostringstream msStream;
msStream << std::put_time(&localTime, "%Y-%m-%d %H:%M:%S")
<< "." << std::setfill('0') << std::setw(3) << milliseconds;
std::cout << "With milliseconds: " << msStream.str() << std::endl;
// With microseconds
std::ostringstream usStream;
usStream << std::put_time(&localTime, "%Y-%m-%d %H:%M:%S")
<< "." << std::setfill('0') << std::setw(6) << microseconds;
std::cout << "With microseconds: " << usStream.str() << std::endl;
// Fractional seconds
std::ostringstream fractionStream;
fractionStream << std::put_time(&localTime, "%H:%M:%S")
<< "." << std::fixed << std::setprecision(6)
<< (microseconds / 1000000.0);
std::cout << "Fractional seconds: " << fractionStream.str() << std::endl;
}
// 3. Windows API formatting
void WindowsAPIFormatting() {
std::cout << "\n=== Windows API Formatting ===" << std::endl;
SYSTEMTIME systemTime;
GetLocalTime(&systemTime);
std::cout << "Windows SYSTEMTIME formatting:" << std::endl;
// Manual formatting
std::cout << "Manual format: "
<< systemTime.wYear << "-"
<< std::setfill('0') << std::setw(2) << systemTime.wMonth << "-"
<< std::setfill('0') << std::setw(2) << systemTime.wDay << " "
<< std::setfill('0') << std::setw(2) << systemTime.wHour << ":"
<< std::setfill('0') << std::setw(2) << systemTime.wMinute << ":"
<< std::setfill('0') << std::setw(2) << systemTime.wSecond << "."
<< std::setfill('0') << std::setw(3) << systemTime.wMilliseconds << std::endl;
// GetDateFormat and GetTimeFormat
SYSTEMTIME dateOnly = systemTime;
SYSTEMTIME timeOnly = systemTime;
// Format date
TCHAR dateBuffer[100];
int dateResult = GetDateFormat(
LOCALE_USER_DEFAULT,
DATE_LONGDATE,
&dateOnly,
NULL,
dateBuffer,
sizeof(dateBuffer) / sizeof(TCHAR)
);
if (dateResult > 0) {
std::wcout << L"Long date format: " << dateBuffer << std::endl;
}
// Format time
TCHAR timeBuffer[100];
int timeResult = GetTimeFormat(
LOCALE_USER_DEFAULT,
TIME_FORCE24HOURFORMAT,
&timeOnly,
NULL,
timeBuffer,
sizeof(timeBuffer) / sizeof(TCHAR)
);
if (timeResult > 0) {
std::wcout << L"24-hour time format: " << timeBuffer << std::endl;
}
// Short date format
TCHAR shortDateBuffer[100];
GetDateFormat(
LOCALE_USER_DEFAULT,
DATE_SHORTDATE,
&dateOnly,
NULL,
shortDateBuffer,
sizeof(shortDateBuffer) / sizeof(TCHAR)
);
std::wcout << L"Short date format: " << shortDateBuffer << std::endl;
// 12-hour time format
TCHAR time12Buffer[100];
GetTimeFormat(
LOCALE_USER_DEFAULT,
0, // Default time format
&timeOnly,
NULL,
time12Buffer,
sizeof(time12Buffer) / sizeof(TCHAR)
);
std::wcout << L"12-hour time format: " << time12Buffer << std::endl;
}
// 4. Localization and locale-specific formatting
void LocaleFormatting() {
std::cout << "\n=== Localization and Locale Formatting ===" << std::endl;
auto now = std::chrono::system_clock::now();
std::time_t currentTime = std::chrono::system_clock::to_time_t(now);
std::tm localTime;
localtime_s(&localTime, ¤tTime);
// Different locale examples
std::vector<std::pair<std::string, std::string>> locales = {
{"", "Default locale"},
{"en_US.UTF-8", "US English"},
{"en_GB.UTF-8", "British English"},
{"de_DE.UTF-8", "German"},
{"fr_FR.UTF-8", "French"},
{"ja_JP.UTF-8", "Japanese"}
};
for (const auto& [localeName, description] : locales) {
std::cout << "\n" << description << ":" << std::endl;
try {
// Set locale for this iteration
std::ostringstream dateStream, timeStream;
if (localeName.empty()) {
// Use system default
dateStream << std::put_time(&localTime, "%x");
timeStream << std::put_time(&localTime, "%X");
} else {
// Try to set specific locale
try {
std::locale::global(std::locale(localeName));
dateStream << std::put_time(&localTime, "%x");
timeStream << std::put_time(&localTime, "%X");
} catch (const std::exception&) {
std::cout << " Locale not available, using default" << std::endl;
dateStream << std::put_time(&localTime, "%x");
timeStream << std::put_time(&localTime, "%X");
}
}
std::cout << " Date: " << dateStream.str() << std::endl;
std::cout << " Time: " << timeStream.str() << std::endl;
} catch (const std::exception& e) {
std::cout << " Error: " << e.what() << std::endl;
}
}
// Reset to default locale
try {
std::locale::global(std::locale(""));
} catch (...) {
// Ignore locale reset errors
}
}
// 5. Custom formatting functions
class TimeFormatter {
public:
// Format with custom pattern
static std::string formatWithPattern(const std::tm& timeInfo, const std::string& pattern) {
std::ostringstream result;
std::string currentPattern = pattern;
// Simple pattern replacement
std::map<std::string, std::string> replacements = {
{"YYYY", std::to_string(timeInfo.tm_year + 1900)},
{"YY", std::to_string((timeInfo.tm_year + 1900) % 100)},
{"MM", std::to_string(timeInfo.tm_mon + 1)},
{"DD", std::to_string(timeInfo.tm_mday)},
{"hh", std::to_string(timeInfo.tm_hour)},
{"mm", std::to_string(timeInfo.tm_min)},
{"ss", std::to_string(timeInfo.tm_sec)},
{"DAY", getDayName(timeInfo.tm_wday)},
{"MONTH", getMonthName(timeInfo.tm_mon)}
};
// Pad single digits with leading zero
std::map<std::string, std::string> paddedReplacements;
for (const auto& [key, value] : replacements) {
if (value.length() == 1) {
paddedReplacements[key] = "0" + value;
} else {
paddedReplacements[key] = value;
}
}
// Apply replacements
for (const auto& [key, value] : paddedReplacements) {
size_t pos = currentPattern.find(key);
while (pos != std::string::npos) {
currentPattern.replace(pos, key.length(), value);
pos = currentPattern.find(key, pos);
}
}
result << currentPattern;
return result.str();
}
// Format time ago
static std::string formatTimeAgo(std::chrono::system_clock::time_point pastTime) {
auto now = std::chrono::system_clock::now();
auto duration = now - pastTime;
auto seconds = std::chrono::duration_cast<std::chrono::seconds>(duration).count();
if (seconds < 60) {
return std::to_string(seconds) + " seconds ago";
}
auto minutes = seconds / 60;
if (minutes < 60) {
return std::to_string(minutes) + " minute" + (minutes == 1 ? "" : "s") + " ago";
}
auto hours = minutes / 60;
if (hours < 24) {
return std::to_string(hours) + " hour" + (hours == 1 ? "" : "s") + " ago";
}
auto days = hours / 24;
if (days < 30) {
return std::to_string(days) + " day" + (days == 1 ? "" : "s") + " ago";
}
auto months = days / 30;
if (months < 12) {
return std::to_string(months) + " month" + (months == 1 ? "" : "s") + " ago";
}
auto years = months / 12;
return std::to_string(years) + " year" + (years == 1 ? "" : "s") + " ago";
}
// Format duration
static std::string formatDuration(std::chrono::milliseconds duration) {
auto totalSeconds = std::chrono::duration_cast<std::chrono::seconds>(duration).count();
auto milliseconds = duration.count() % 1000;
auto hours = totalSeconds / 3600;
auto minutes = (totalSeconds % 3600) / 60;
auto seconds = totalSeconds % 60;
std::ostringstream result;
if (hours > 0) {
result << hours << "h " << minutes << "m " << seconds << "." << std::setfill('0')
<< std::setw(3) << milliseconds << "s";
} else if (minutes > 0) {
result << minutes << "m " << seconds << "." << std::setfill('0')
<< std::setw(3) << milliseconds << "s";
} else {
result << seconds << "." << std::setfill('0') << std::setw(3) << milliseconds << "s";
}
return result.str();
}
private:
static std::string getDayName(int dayOfWeek) {
static const std::vector<std::string> dayNames = {
"Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"
};
return (dayOfWeek >= 0 && dayOfWeek < 7) ? dayNames[dayOfWeek] : "Unknown";
}
static std::string getMonthName(int month) {
static const std::vector<std::string> monthNames = {
"January", "February", "March", "April", "May", "June",
"July", "August", "September", "October", "November", "December"
};
return (month >= 0 && month < 12) ? monthNames[month] : "Unknown";
}
};
void demonstrateCustomFormatting() {
std::cout << "\n=== Custom Formatting Functions ===" << std::endl;
auto now = std::chrono::system_clock::now();
std::time_t currentTime = std::chrono::system_clock::to_time_t(now);
std::tm localTime;
localtime_s(&localTime, ¤tTime);
std::cout << "Custom pattern formatting:" << std::endl;
std::cout << " YYYY-MM-DD hh:mm:ss: "
<< TimeFormatter::formatWithPattern(localTime, "YYYY-MM-DD hh:mm:ss") << std::endl;
std::cout << " DD/MM/YYYY: "
<< TimeFormatter::formatWithPattern(localTime, "DD/MM/YYYY") << std::endl;
std::cout << " MONTH DD, YYYY: "
<< TimeFormatter::formatWithPattern(localTime, "MONTH DD, YYYY") << std::endl;
std::cout << " DAY, MONTH DD, hh:mm: "
<< TimeFormatter::formatWithPattern(localTime, "DAY, MONTH DD, hh:mm") << std::endl;
// Time ago examples
auto pastTime = now - std::chrono::minutes(5);
std::cout << "\nTime ago examples:" << std::endl;
std::cout << " 5 minutes ago: " << TimeFormatter::formatTimeAgo(pastTime) << std::endl;
pastTime = now - std::chrono::hours(2);
std::cout << " 2 hours ago: " << TimeFormatter::formatTimeAgo(pastTime) << std::endl;
pastTime = now - std::chrono::hours(24 * 3);
std::cout << " 3 days ago: " << TimeFormatter::formatTimeAgo(pastTime) << std::endl;
pastTime = now - std::chrono::hours(24 * 30 * 2);
std::cout << " 2 months ago: " << TimeFormatter::formatTimeAgo(pastTime) << std::endl;
// Duration formatting
std::cout << "\nDuration formatting:" << std::endl;
auto duration1 = std::chrono::milliseconds(1500);
auto duration2 = std::chrono::milliseconds(125000);
auto duration3 = std::chrono::milliseconds(3661500);
std::cout << " 1500ms: " << TimeFormatter::formatDuration(duration1) << std::endl;
std::cout << " 125000ms: " << TimeFormatter::formatDuration(duration2) << std::endl;
std::cout << " 3661500ms: " << TimeFormatter::formatDuration(duration3) << std::endl;
}
// 6. Log timestamp formatting
void logTimestampFormatting() {
std::cout << "\n=== Log Timestamp Formatting ===" << std::endl;
auto now = std::chrono::system_clock::now();
auto timeMs = std::chrono::time_point_cast<std::chrono::milliseconds>(now);
std::time_t currentTime = std::chrono::system_clock::to_time_t(now);
std::tm localTime;
localtime_s(&localTime, ¤tTime);
auto epochMs = timeMs.time_since_epoch().count();
int milliseconds = static_cast<int>(epochMs % 1000);
// Different log formats
std::vector<std::pair<std::string, std::string>> logFormats = {
{"Standard", "[%Y-%m-%d %H:%M:%S]"},
{"With Milliseconds", "[%Y-%m-%d %H:%M:%S.%e]"},
{"ISO 8601", "[%Y-%m-%dT%H:%M:%S.%eZ]"},
{"Compact", "[%Y%m%d_%H%M%S]"},
{"Detailed", "[%Y-%m-%d %H:%M:%S.%e %Z]"},
{"RFC 3339", "[%Y-%m-%dT%H:%M:%S.%e%z]"}
};
std::cout << "Log timestamp formats:" << std::endl;
for (const auto& [name, pattern] : logFormats) {
std::ostringstream logStream;
// Replace %e with milliseconds for our custom formatting
std::string customPattern = pattern;
size_t pos = customPattern.find("%e");
if (pos != std::string::npos) {
customPattern.replace(pos, 2, std::to_string(milliseconds));
}
logStream << std::put_time(&localTime, customPattern.c_str());
std::cout << " " << name << ": " << logStream.str() << " [LOG MESSAGE]" << std::endl;
}
// Computer-readable format (Unix timestamp with milliseconds)
double unixTimestampMs = static_cast<double>(currentTime) * 1000.0 + milliseconds;
std::cout << "\nUnix timestamp (ms): " << std::fixed << std::setprecision(0)
<< unixTimestampMs << std::endl;
// High-resolution timestamp
auto highRes = std::chrono::high_resolution_clock::now();
auto highResEpoch = highRes.time_since_epoch().count();
std::cout << "High-res timestamp: " << highResEpoch << " nanoseconds since epoch" << std::endl;
}
// 7. Colorized and styled formatting
void styledFormatting() {
std::cout << "\n=== Styled Formatting ===" << std::endl;
auto now = std::chrono::system_clock::now();
std::time_t currentTime = std::chrono::system_clock::to_time_t(now);
std::tm localTime;
localtime_s(&localTime, ¤tTime);
// For demonstration purposes, we'll show styled text with markers
// In a real console application, you could use ANSI color codes
std::cout << "Styled timestamp examples (using markers):" << std::endl;
// Digital clock style
std::ostringstream digitalClock;
digitalClock << "[" << std::setfill('0') << std::setw(2) << localTime.tm_hour
<< ":" << std::setfill('0') << std::setw(2) << localTime.tm_min
<< ":" << std::setfill('0') << std::setw(2) << localTime.tm_sec << "]";
std::cout << " Digital clock: " << digitalClock.str() << std::endl;
// Binary time (for fun)
std::cout << " Binary time: ";
std::cout << "[" << std::bitset<6>(localTime.tm_hour).to_string()
<< ":" << std::bitset<6>(localTime.tm_min).to_string()
<< ":" << std::bitset<6>(localTime.tm_sec).to_string() << "]" << std::endl;
// Calendar style
std::ostringstream calendar;
calendar << std::put_time(&localTime, "%B %d, %Y");
std::cout << " Calendar: " << calendar.str() << std::endl;
// Military time
std::ostringstream military;
military << std::setfill('0') << std::setw(2) << localTime.tm_hour
<< std::setfill('0') << std::setw(2) << localTime.tm_min
<< "HRS";
std::cout << " Military: " << military.str() << std::endl;
// Word clock
std::string timeWords = convertToWords(localTime.tm_hour, localTime.tm_min);
std::cout << " Word clock: " << timeWords << std::endl;
// Progress bar style (representing time of day)
int dayProgress = (localTime.tm_hour * 3600 + localTime.tm_min * 60 + localTime.tm_sec) * 100 / 86400;
std::cout << " Day progress: [";
for (int i = 0; i < 20; i++) {
if (i < dayProgress / 5) {
std::cout << "=";
} else {
std::cout << " ";
}
}
std::cout << "] " << dayProgress << "%" << std::endl;
}
// Helper function to convert time to words
std::string convertToWords(int hour, int minute) {
static const std::vector<std::string> numbers = {
"twelve", "one", "two", "three", "four", "five",
"six", "seven", "eight", "nine", "ten", "eleven"
};
hour = hour % 12;
if (hour == 0) hour = 12;
std::string result = numbers[hour % 12];
if (minute == 0) {
result += " o'clock";
} else if (minute <= 30) {
if (minute == 15) {
result = "a quarter past " + result;
} else if (minute == 30) {
result = "half past " + result;
} else {
result = numbers[minute] + " past " + result;
}
} else {
int nextHour = hour % 12 + 1;
if (nextHour == 13) nextHour = 1;
if (minute == 45) {
result = "a quarter to " + numbers[nextHour % 12];
} else {
result = numbers[60 - minute] + " to " + numbers[nextHour % 12];
}
}
return result;
}
int main() {
std::cout << "=== C++ Windows Date and Time - Time Formatting ===" << std::endl;
std::cout << "Demonstrating comprehensive time formatting and display techniques\n" << std::endl;
try {
// Run all formatting examples
BasicTimeFormatting();
HighResolutionFormatting();
WindowsAPIFormatting();
LocaleFormatting();
demonstrateCustomFormatting();
logTimestampFormatting();
styledFormatting();
std::cout << "\nAll time formatting examples completed successfully!" << std::endl;
} catch (const std::exception& e) {
std::cerr << "Unexpected error: " << e.what() << std::endl;
return 1;
}
return 0;
}
💻 Análisis y Validación de Hora cpp
🔴 complex
⭐⭐⭐⭐
Analizar varios formatos de cadena de tiempo y validar entradas de tiempo con manejo de errores
⏱️ 30 min
🏷️ cpp, datetime, parsing, validation, windows
Prerequisites:
Advanced C++ regex, Time formats, Error handling patterns, Validation techniques
#include <iostream>
#include <string>
#include <sstream>
#include <vector>
#include <regex>
#include <chrono>
#include <ctime>
#include <iomanip>
#include <map>
#include <stdexcept>
#include <algorithm>
// Custom exception for time parsing errors
class TimeParseException : public std::runtime_error {
public:
TimeParseException(const std::string& message) : std::runtime_error(message) {}
};
// 1. Basic time parsing functions
class TimeParser {
public:
// Parse ISO 8601 format: YYYY-MM-DDTHH:MM:SS
static std::tm parseISO8601(const std::string& timeString) {
std::tm timeInfo = {};
std::istringstream iss(timeString);
iss >> std::get_time(&timeInfo, "%Y-%m-%dT%H:%M:%S");
if (iss.fail()) {
throw TimeParseException("Failed to parse ISO 8601 format: " + timeString);
}
return timeInfo;
}
// Parse US format: MM/DD/YYYY HH:MM:SS
static std::tm parseUSFormat(const std::string& timeString) {
std::tm timeInfo = {};
std::istringstream iss(timeString);
iss >> std::get_time(&timeInfo, "%m/%d/%Y %H:%M:%S");
if (iss.fail()) {
throw TimeParseException("Failed to parse US format: " + timeString);
}
return timeInfo;
}
// Parse European format: DD.MM.YYYY HH:MM:SS
static std::tm parseEuropeanFormat(const std::string& timeString) {
std::tm timeInfo = {};
std::istringstream iss(timeString);
iss >> std::get_time(&timeInfo, "%d.%m.%Y %H:%M:%S");
if (iss.fail()) {
throw TimeParseException("Failed to parse European format: " + timeString);
}
return timeInfo;
}
// Parse flexible format with multiple patterns
static std::tm parseFlexible(const std::string& timeString) {
std::vector<std::string> patterns = {
"%Y-%m-%d %H:%M:%S",
"%Y-%m-%dT%H:%M:%S",
"%m/%d/%Y %H:%M:%S",
"%d.%m.%Y %H:%M:%S",
"%d-%b-%Y %H:%M:%S",
"%b %d %H:%M:%S %Y",
"%x %X",
"%c"
};
std::tm timeInfo = {};
for (const auto& pattern : patterns) {
std::istringstream iss(timeString);
iss >> std::get_time(&timeInfo, pattern.c_str());
if (!iss.fail()) {
return timeInfo;
}
}
throw TimeParseException("Failed to parse time with any known pattern: " + timeString);
}
// Parse time-only string (HH:MM:SS)
static std::tm parseTimeOnly(const std::string& timeString) {
std::tm timeInfo = {};
// Set date to current date
auto now = std::chrono::system_clock::now();
std::time_t currentTime = std::chrono::system_clock::to_time_t(now);
localtime_s(&timeInfo, ¤tTime);
std::istringstream iss(timeString);
iss >> std::get_time(&timeInfo, "%H:%M:%S");
if (iss.fail()) {
throw TimeParseException("Failed to parse time: " + timeString);
}
return timeInfo;
}
// Parse date-only string (YYYY-MM-DD)
static std::tm parseDateOnly(const std::string& dateString) {
std::tm timeInfo = {};
// Set time to midnight
timeInfo.tm_hour = 0;
timeInfo.tm_min = 0;
timeInfo.tm_sec = 0;
std::istringstream iss(dateString);
iss >> std::get_time(&timeInfo, "%Y-%m-%d");
if (iss.fail()) {
// Try other date formats
iss.clear();
iss.str(dateString);
iss >> std::get_time(&timeInfo, "%m/%d/%Y");
}
if (iss.fail()) {
iss.clear();
iss.str(dateString);
iss >> std::get_time(&timeInfo, "%d.%m.%Y");
}
if (iss.fail()) {
throw TimeParseException("Failed to parse date: " + dateString);
}
return timeInfo;
}
};
void demonstrateBasicParsing() {
std::cout << "=== Basic Time Parsing ===" << std::endl;
std::vector<std::pair<std::string, std::string>> testStrings = {
{"ISO 8601", "2023-12-25T14:30:45"},
{"US Format", "12/25/2023 14:30:45"},
{"European Format", "25.12.2023 14:30:45"},
{"Flexible", "Dec 25 14:30:45 2023"}
};
for (const auto& [name, timeString] : testStrings) {
try {
std::tm timeInfo;
if (name == "ISO 8601") {
timeInfo = TimeParser::parseISO8601(timeString);
} else if (name == "US Format") {
timeInfo = TimeParser::parseUSFormat(timeString);
} else if (name == "European Format") {
timeInfo = TimeParser::parseEuropeanFormat(timeString);
} else {
timeInfo = TimeParser::parseFlexible(timeString);
}
std::cout << name << " (" << timeString << "): ";
std::cout << (timeInfo.tm_year + 1900) << "-"
<< (timeInfo.tm_mon + 1) << "-"
<< timeInfo.tm_mday << " "
<< timeInfo.tm_hour << ":"
<< timeInfo.tm_min << ":"
<< timeInfo.tm_sec << std::endl;
} catch (const TimeParseException& e) {
std::cout << name << ": Error - " << e.what() << std::endl;
}
}
// Time-only and date-only parsing
std::cout << "\nTime-only and date-only parsing:" << std::endl;
try {
std::tm timeOnly = TimeParser::parseTimeOnly("14:30:45");
std::cout << "Time only: " << timeOnly.tm_hour << ":"
<< timeOnly.tm_min << ":" << timeOnly.tm_sec << std::endl;
std::tm dateOnly = TimeParser::parseDateOnly("2023-12-25");
std::cout << "Date only: " << (dateOnly.tm_year + 1900) << "-"
<< (dateOnly.tm_mon + 1) << "-" << dateOnly.tm_mday << std::endl;
} catch (const TimeParseException& e) {
std::cout << "Error: " << e.what() << std::endl;
}
}
// 2. Advanced parsing with regex
class RegexTimeParser {
public:
struct ParsedTime {
int year = 0;
int month = 0;
int day = 0;
int hour = 0;
int minute = 0;
int second = 0;
int millisecond = 0;
std::string timezone;
bool isValid = false;
};
// Parse with flexible regex patterns
static ParsedTime parseWithRegex(const std::string& timeString) {
ParsedTime result;
// Define regex patterns for different time formats
std::vector<std::pair<std::regex, std::function<void(std::smatch&)>>> patterns = {
// ISO 8601 with timezone: 2023-12-25T14:30:45.123+05:30
{
std::regex(R"(^(d{4})-(d{2})-(d{2})T(d{2}):(d{2}):(d{2})(?:.(d{3}))?(?:([+-]d{2}:d{2})|Z)?$)"),
[&result](std::smatch& match) {
result.year = std::stoi(match[1].str());
result.month = std::stoi(match[2].str());
result.day = std::stoi(match[3].str());
result.hour = std::stoi(match[4].str());
result.minute = std::stoi(match[5].str());
result.second = std::stoi(match[6].str());
if (match[7].matched) {
result.millisecond = std::stoi(match[7].str());
}
if (match[8].matched) {
result.timezone = match[8].str();
} else if (match[0].str().back() == 'Z') {
result.timezone = "UTC";
}
result.isValid = true;
}
},
// Natural language: December 25, 2023 at 2:30 PM
{
std::regex(R"(^(w+)s+(d{1,2}),s+(d{4})s+ats+(d{1,2}):(d{2})(?::(d{2}))?s*(AM|PM)?$)"),
[&result](std::smatch& match) {
static std::map<std::string, int> monthMap = {
{"January", 1}, {"February", 2}, {"March", 3}, {"April", 4},
{"May", 5}, {"June", 6}, {"July", 7}, {"August", 8},
{"September", 9}, {"October", 10}, {"November", 11}, {"December", 12},
{"Jan", 1}, {"Feb", 2}, {"Mar", 3}, {"Apr", 4}, {"May", 5}, {"Jun", 6},
{"Jul", 7}, {"Aug", 8}, {"Sep", 9}, {"Oct", 10}, {"Nov", 11}, {"Dec", 12}
};
result.month = monthMap[match[1].str()];
result.day = std::stoi(match[2].str());
result.year = std::stoi(match[3].str());
result.hour = std::stoi(match[4].str());
result.minute = std::stoi(match[5].str());
if (match[6].matched) {
result.second = std::stoi(match[6].str());
}
if (match[7].matched) {
std::string period = match[7].str();
if (period == "PM" && result.hour != 12) {
result.hour += 12;
} else if (period == "AM" && result.hour == 12) {
result.hour = 0;
}
}
result.isValid = true;
}
},
// Relative time: "yesterday at 3 PM", "in 2 hours"
{
std::regex(R"(^(yesterday|today|tomorrow)(?:s+ats+(d{1,2})(?::(d{2}))?s*(AM|PM))?$)"),
[&result](std::smatch& match) {
auto now = std::chrono::system_clock::now();
std::time_t currentTime = std::chrono::system_clock::to_time_t(now);
std::tm localTime;
localtime_s(&localTime, ¤tTime);
result.year = localTime.tm_year + 1900;
result.month = localTime.tm_mon + 1;
result.day = localTime.tm_mday;
result.hour = localTime.tm_hour;
result.minute = localTime.tm_min;
result.second = localTime.tm_sec;
std::string dayModifier = match[1].str();
if (dayModifier == "yesterday") {
result.day -= 1;
} else if (dayModifier == "tomorrow") {
result.day += 1;
}
if (match[2].matched) {
result.hour = std::stoi(match[2].str());
result.minute = match[3].matched ? std::stoi(match[3].str()) : 0;
result.second = 0;
if (match[4].matched) {
std::string period = match[4].str();
if (period == "PM" && result.hour != 12) {
result.hour += 12;
} else if (period == "AM" && result.hour == 12) {
result.hour = 0;
}
}
}
result.isValid = true;
}
}
};
// Try each pattern
for (const auto& [pattern, processor] : patterns) {
std::smatch match;
if (std::regex_search(timeString, match, pattern)) {
processor(match);
if (result.isValid) {
break;
}
}
}
return result;
}
// Convert ParsedTime to std::tm
static std::tm toTm(const ParsedTime& parsedTime) {
std::tm timeInfo = {};
timeInfo.tm_year = parsedTime.year - 1900;
timeInfo.tm_mon = parsedTime.month - 1;
timeInfo.tm_mday = parsedTime.day;
timeInfo.tm_hour = parsedTime.hour;
timeInfo.tm_min = parsedTime.minute;
timeInfo.tm_sec = parsedTime.second;
// Normalize the time structure
std::time_t normalizedTime = std::mktime(&timeInfo);
localtime_s(&timeInfo, &normalizedTime);
return timeInfo;
}
};
void demonstrateRegexParsing() {
std::cout << "\n=== Advanced Regex Parsing ===" << std::endl;
std::vector<std::string> testStrings = {
"2023-12-25T14:30:45.123+05:30",
"December 25, 2023 at 2:30 PM",
"tomorrow at 3 PM",
"yesterday",
"2024-01-01T00:00:00Z"
};
for (const auto& timeString : testStrings) {
auto parsed = RegexTimeParser::parseWithRegex(timeString);
std::cout << "Parsing: '" << timeString << "'" << std::endl;
if (parsed.isValid) {
std::cout << " Result: " << parsed.year << "-"
<< std::setfill('0') << std::setw(2) << parsed.month << "-"
<< std::setfill('0') << std::setw(2) << parsed.day << " "
<< std::setfill('0') << std::setw(2) << parsed.hour << ":"
<< std::setfill('0') << std::setw(2) << parsed.minute << ":"
<< std::setfill('0') << std::setw(2) << parsed.second;
if (parsed.millisecond > 0) {
std::cout << "." << std::setfill('0') << std::setw(3) << parsed.millisecond;
}
if (!parsed.timezone.empty()) {
std::cout << " " << parsed.timezone;
}
std::cout << std::endl;
// Convert to std::tm and verify
try {
std::tm timeInfo = RegexTimeParser::toTm(parsed);
std::ostringstream oss;
oss << std::put_time(&timeInfo, "%Y-%m-%d %H:%M:%S");
std::cout << " Normalized: " << oss.str() << std::endl;
} catch (const std::exception& e) {
std::cout << " Normalization error: " << e.what() << std::endl;
}
} else {
std::cout << " Failed to parse" << std::endl;
}
std::cout << std::endl;
}
}
// 3. Time validation
class TimeValidator {
public:
struct ValidationResult {
bool isValid;
std::vector<std::string> errors;
std::vector<std::string> warnings;
};
// Validate parsed time components
static ValidationResult validateTime(const RegexTimeParser::ParsedTime& parsedTime) {
ValidationResult result;
result.isValid = true;
// Basic range validation
if (parsedTime.year < 1900 || parsedTime.year > 2100) {
result.errors.push_back("Year out of valid range (1900-2100)");
result.isValid = false;
}
if (parsedTime.month < 1 || parsedTime.month > 12) {
result.errors.push_back("Month out of valid range (1-12)");
result.isValid = false;
}
if (parsedTime.day < 1 || parsedTime.day > 31) {
result.errors.push_back("Day out of valid range (1-31)");
result.isValid = false;
}
if (parsedTime.hour < 0 || parsedTime.hour > 23) {
result.errors.push_back("Hour out of valid range (0-23)");
result.isValid = false;
}
if (parsedTime.minute < 0 || parsedTime.minute > 59) {
result.errors.push_back("Minute out of valid range (0-59)");
result.isValid = false;
}
if (parsedTime.second < 0 || parsedTime.second > 59) {
result.errors.push_back("Second out of valid range (0-59)");
result.isValid = false;
}
if (parsedTime.millisecond < 0 || parsedTime.millisecond > 999) {
result.errors.push_back("Millisecond out of valid range (0-999)");
result.isValid = false;
}
// Validate day against month
if (parsedTime.isValid) {
int maxDay = getDaysInMonth(parsedTime.year, parsedTime.month);
if (parsedTime.day > maxDay) {
result.errors.push_back("Day " + std::to_string(parsedTime.day) +
" is invalid for month " + std::to_string(parsedTime.month) +
" (max: " + std::to_string(maxDay) + ")");
result.isValid = false;
}
}
// Check for suspicious but valid dates
if (parsedTime.month == 2 && parsedTime.day == 29) {
bool isLeapYear = (parsedTime.year % 4 == 0 && parsedTime.year % 100 != 0) ||
(parsedTime.year % 400 == 0);
if (!isLeapYear) {
result.errors.push_back("February 29 is invalid in non-leap year");
result.isValid = false;
}
}
// Warnings (doesn't make it invalid)
if (parsedTime.year == 1900) {
result.warnings.push_back("Year 1900 might indicate missing or default date");
}
if (parsedTime.month == 0 || parsedTime.day == 0) {
result.warnings.push_back("Zero month or day might indicate parsing error");
}
if (parsedTime.hour == 0 && parsedTime.minute == 0 && parsedTime.second == 0) {
result.warnings.push_back("Midnight time might be default/empty");
}
return result;
}
// Validate time string format
static ValidationResult validateFormat(const std::string& timeString) {
ValidationResult result;
result.isValid = true;
// Basic format checks
if (timeString.empty()) {
result.errors.push_back("Empty time string");
result.isValid = false;
return result;
}
// Check for invalid characters
std::string validChars = "0123456789-:.T +ZAPMMDaytuehYonlgirjfbvskc";
for (char c : timeString) {
if (validChars.find(c) == std::string::npos && !std::isspace(c)) {
result.warnings.push_back("Potentially invalid character: '" + std::string(1, c) + "'");
}
}
// Check format patterns
bool hasDate = false;
bool hasTime = false;
bool hasSeparator = false;
// Date patterns
if (timeString.find('-') != std::string::npos ||
timeString.find('/') != std::string::npos ||
timeString.find('.') != std::string::npos) {
hasDate = true;
}
// Time patterns
if (timeString.find(':') != std::string::npos) {
hasTime = true;
}
// ISO 8601 separator
if (timeString.find('T') != std::string::npos) {
hasSeparator = true;
}
if (hasDate && hasTime && !hasSeparator && timeString.find(' ') == std::string::npos) {
result.warnings.push_back("Date and time without separator");
}
return result;
}
private:
// Get number of days in month
static int getDaysInMonth(int year, int month) {
static const int daysInMonth[] = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
if (month == 2) {
// Check for leap year
bool isLeapYear = (year % 4 == 0 && year % 100 != 0) || (year % 400 == 0);
return isLeapYear ? 29 : 28;
}
if (month >= 1 && month <= 12) {
return daysInMonth[month - 1];
}
return 31; // Default
}
};
void demonstrateValidation() {
std::cout << "\n=== Time Validation ===" << std::endl;
std::vector<std::string> testStrings = {
"2023-02-29T12:00:00", // Invalid: 2023 is not leap year
"2024-02-30T12:00:00", // Invalid: February never has 30 days
"2023-13-01T12:00:00", // Invalid: Month 13
"2023-12-32T12:00:00", // Invalid: Day 32
"2023-12-25T25:00:00", // Invalid: Hour 25
"2023-12-25T12:60:00", // Invalid: Minute 60
"2024-02-29T12:00:00", // Valid: Leap year
"2023-12-25T00:00:00", // Valid but warning: Midnight default
"0000-01-01T00:00:00", // Valid but warning: Year 1900 default
"invalid-time-string" // Invalid format
};
for (const auto& timeString : testStrings) {
std::cout << "\nValidating: '" << timeString << "'" << std::endl;
// First validate format
auto formatResult = TimeValidator::validateFormat(timeString);
if (!formatResult.isValid) {
std::cout << " Format invalid:" << std::endl;
for (const auto& error : formatResult.errors) {
std::cout << " ERROR: " << error << std::endl;
}
continue;
}
if (!formatResult.warnings.empty()) {
std::cout << " Format warnings:" << std::endl;
for (const auto& warning : formatResult.warnings) {
std::cout << " WARNING: " << warning << std::endl;
}
}
// Try to parse and validate components
try {
auto parsed = RegexTimeParser::parseWithRegex(timeString);
if (!parsed.isValid) {
std::cout << " Parsing failed" << std::endl;
continue;
}
auto validationResult = TimeValidator::validateTime(parsed);
if (validationResult.isValid) {
std::cout << " VALID: " << parsed.year << "-"
<< std::setfill('0') << std::setw(2) << parsed.month << "-"
<< std::setfill('0') << std::setw(2) << parsed.day << " "
<< std::setfill('0') << std::setw(2) << parsed.hour << ":"
<< std::setfill('0') << std::setw(2) << parsed.minute << ":"
<< std::setfill('0') << std::setw(2) << parsed.second << std::endl;
} else {
std::cout << " INVALID:" << std::endl;
for (const auto& error : validationResult.errors) {
std::cout << " ERROR: " << error << std::endl;
}
}
if (!validationResult.warnings.empty()) {
std::cout << " Warnings:" << std::endl;
for (const auto& warning : validationResult.warnings) {
std::cout << " WARNING: " << warning << std::endl;
}
}
} catch (const std::exception& e) {
std::cout << " Parsing error: " << e.what() << std::endl;
}
}
}
// 4. Bulk parsing and error handling
void bulkParsingDemo() {
std::cout << "\n=== Bulk Parsing with Error Handling ===" << std::endl;
std::vector<std::string> timeStrings = {
"2023-12-25 14:30:00",
"invalid-format",
"2023-02-29 00:00:00", // Invalid: not leap year
"",
"2023-13-01 12:00:00", // Invalid month
"2024-02-29T12:30:45Z", // Valid
"not-a-time",
"2023-12-25 25:00:00" // Invalid hour
};
std::vector<std::tm> successfulParses;
std::vector<std::pair<std::string, std::string>> failures;
std::cout << "Parsing " << timeStrings.size() << " time strings..." << std::endl;
for (const auto& timeString : timeStrings) {
try {
std::tm timeInfo = TimeParser::parseFlexible(timeString);
successfulParses.push_back(timeInfo);
std::cout << "✓ Successfully parsed: '" << timeString << "'" << std::endl;
} catch (const TimeParseException& e) {
failures.emplace_back(timeString, e.what());
std::cout << "✗ Failed to parse: '" << timeString << "' - " << e.what() << std::endl;
}
}
std::cout << "\nResults:" << std::endl;
std::cout << "Successfully parsed: " << successfulParses.size() << std::endl;
std::cout << "Failed to parse: " << failures.size() << std::endl;
if (!successfulParses.empty()) {
std::cout << "\nSuccessfully parsed times:" << std::endl;
for (const auto& timeInfo : successfulParses) {
std::ostringstream oss;
oss << std::put_time(&timeInfo, "%Y-%m-%d %H:%M:%S");
std::cout << " " << oss.str() << std::endl;
}
}
if (!failures.empty()) {
std::cout << "\nFailed parses:" << std::endl;
for (const auto& [input, error] : failures) {
std::cout << " '" << input << "' → " << error << std::endl;
}
}
}
// 5. Conversion between time representations
void demonstrateTimeConversion() {
std::cout << "\n=== Time Representation Conversion ===" << std::endl;
// Start with a known time string
std::string timeString = "2023-12-25T14:30:45";
try {
// Parse to std::tm
std::tm timeInfo = TimeParser::parseISO8601(timeString);
// Convert to different representations
std::cout << "Original: " << timeString << std::endl;
// To time_t
std::time_t timeT = std::mktime(&timeInfo);
std::cout << "time_t: " << timeT << std::endl;
// To system_clock time_point
auto systemTime = std::chrono::system_clock::from_time_t(timeT);
std::cout << "system_clock: " << systemTime.time_since_epoch().count() << " ticks" << std::endl;
// To FILETIME (Windows)
FILETIME fileTime;
SYSTEMTIME systemTimeWin;
// Convert tm to SYSTEMTIME
systemTimeWin.wYear = timeInfo.tm_year + 1900;
systemTimeWin.wMonth = timeInfo.tm_mon + 1;
systemTimeWin.wDay = timeInfo.tm_mday;
systemTimeWin.wHour = timeInfo.tm_hour;
systemTimeWin.wMinute = timeInfo.tm_min;
systemTimeWin.wSecond = timeInfo.tm_sec;
systemTimeWin.wMilliseconds = 0;
systemTimeWin.wDayOfWeek = timeInfo.tm_wday;
if (SystemTimeToFileTime(&systemTimeWin, &fileTime)) {
ULARGE_INTEGER uli;
uli.LowPart = fileTime.dwLowDateTime;
uli.HighPart = fileTime.dwHighDateTime;
std::cout << "FILETIME: " << uli.QuadPart << " (100-nanosecond intervals)" << std::endl;
}
// Back to string in different formats
std::ostringstream isoStream;
isoStream << std::put_time(&timeInfo, "%Y-%m-%dT%H:%M:%S");
std::cout << "Back to ISO string: " << isoStream.str() << std::endl;
std::ostringstream usStream;
usStream << std::put_time(&timeInfo, "%m/%d/%Y %I:%M:%S %p");
std::cout << "US format: " << usStream.str() << std::endl;
std::ostringstream readableStream;
readableStream << std::put_time(&timeInfo, "%A, %B %d, %Y at %I:%M %p");
std::cout << "Readable: " << readableStream.str() << std::endl;
} catch (const std::exception& e) {
std::cout << "Error: " << e.what() << std::endl;
}
}
int main() {
std::cout << "=== C++ Windows Date and Time - Time Parsing ===" << std::endl;
std::cout << "Demonstrating comprehensive time parsing and validation techniques\n" << std::endl;
try {
// Run all parsing examples
demonstrateBasicParsing();
demonstrateRegexParsing();
demonstrateValidation();
bulkParsingDemo();
demonstrateTimeConversion();
std::cout << "\nAll time parsing examples completed successfully!" << std::endl;
} catch (const std::exception& e) {
std::cerr << "Unexpected error: " << e.what() << std::endl;
return 1;
}
return 0;
}