如何使用C++获取RIFF格式WAV文件的创建时间
Alright, let's break down how to turn that TimeStamp field in your META_DATA chunk into a usable creation date and time. First, let's confirm the basics: your TimeStamp stores seconds since the Unix epoch (January 1, 1970, 00:00:00 UTC) — that's the standard for most timestamp fields like this.
Step 1: Ensure Proper Struct Parsing
First, make sure your META_DATA struct is correctly aligned to match the file's byte layout. C++ compilers often add padding between struct members, which can mess up reading from the file. Fix this with packing directives:
#pragma pack(push, 1) typedef struct META_DATA { char meta[4]; uint32_t HeadData; // <头部数据长度 - 8> uint8_t Version; uint8_t Model; uint32_t Serial; uint32_t RecordingNumber; uint16_t ChunkNumber; uint32_t TimeStamp; uint32_t MetadataChecksum; } META_DATA; #pragma pack(pop)
This ensures no extra padding is added, so the struct matches exactly what's in the WAV file.
Step 2: Convert Timestamp to DateTime (C++11+)
For modern C++ (C++11 and later), use the <chrono> library for type-safe time handling. Here's how to convert the epoch seconds to both local time and UTC:
#include <chrono> #include <ctime> #include <iostream> #include <string> // Assume you've already parsed the META_DATA chunk into this variable META_DATA parsed_meta; // Extract the epoch timestamp uint32_t epoch_secs = parsed_meta.TimeStamp; // Convert to a system clock time point std::chrono::system_clock::time_point time_point = std::chrono::system_clock::from_time_t(static_cast<std::time_t>(epoch_secs)); // Convert to local time (thread-safe variant for Windows) std::time_t local_time_t = std::chrono::system_clock::to_time_t(time_point); std::tm local_tm{}; localtime_s(&local_tm, &local_time_t); // Format into a human-readable string char local_buffer[26]; std::strftime(local_buffer, sizeof(local_buffer), "%Y-%m-%d %H:%M:%S", &local_tm); std::string local_creation_time(local_buffer); std::cout << "Local Creation Time: " << local_creation_time << "\n"; // Convert to UTC time (thread-safe variant) std::tm utc_tm{}; gmtime_s(&utc_tm, &local_time_t); char utc_buffer[26]; std::strftime(utc_buffer, sizeof(utc_buffer), "%Y-%m-%d %H:%M:%S", &utc_tm); std::string utc_creation_time(utc_buffer); std::cout << "UTC Creation Time: " << utc_creation_time << "\n";
Note: For POSIX systems (Linux/macOS), use localtime_r and gmtime_r instead of localtime_s/gmtime_s for thread safety.
Step 3: Legacy C++ (Pre-C++11)
If you're working with an older C++ standard, use the C-style time functions directly:
#include <ctime> #include <iostream> #include <string> META_DATA parsed_meta; uint32_t epoch_secs = parsed_meta.TimeStamp; std::time_t raw_time = static_cast<std::time_t>(epoch_secs); // Local time (note: localtime is NOT thread-safe) std::tm* local_tm = std::localtime(&raw_time); char local_buffer[26]; std::strftime(local_buffer, sizeof(local_buffer), "%Y-%m-%d %H:%M:%S", local_tm); std::cout << "Local Creation Time: " << local_buffer << "\n"; // UTC time (gmtime is also NOT thread-safe) std::tm* utc_tm = std::gmtime(&raw_time); char utc_buffer[26]; std::strftime(utc_buffer, sizeof(utc_buffer), "%Y-%m-%d %H:%M:%S", utc_tm); std::cout << "UTC Creation Time: " << utc_buffer << "\n";
Key Notes
- Epoch Confirmation: Double-check that your
TimeStampuses the Unix epoch. If it's a different epoch (e.g., Windows file time starts at 1601-01-01), you'll need to adjust the timestamp by adding the offset between epochs. - Thread Safety: Avoid using
localtime/gmtimein multi-threaded code. Stick to the thread-safe variants mentioned above. - Timestamp Limits: A
uint32_ttimestamp can represent up to 2106-02-07 UTC (since 2^32 seconds is ~136 years). If your WAV files might have timestamps beyond that, consider updating the struct to useuint64_t.
内容的提问来源于stack exchange,提问作者user17261842

