Why does mktime () change the day of my tm structure?

I read two lines with Year, Julian day (year), hour, minute and observation.

I pull out the appropriate variables using sscanf:

sscanf(tide_str1.c_str(), "%d %d %d %d %Lf", &y1, &j1, &h1, &m1, &obs1); sscanf(tide_str2.c_str(), "%d %d %d %d %Lf", &y2, &j2, &h2, &m2, &obs2); 

For this particular data set, values ​​are: 2011 083 23 22 1.1

Then I create and populate the tm structure and run mktime, with cout calls during the day between them and changes from 083 to 364.

 int y1=2011, j1=83, h1=23, m1=22; struct tm time_struct = {0, 0, 0, 0, 0, 0, 0, 0, 0}, *time_ptr = &time_struct; time_t tv_min; time_struct.tm_year = y1 - 1900; time_struct.tm_yday = j1; cout << time_struct.tm_yday << endl; time_struct.tm_hour = h1; time_struct.tm_min = m1; time_struct.tm_isdst = -1; cout << time_struct.tm_yday << endl; tv_min = mktime(time_ptr); cout << time_struct.tm_yday << endl; 

Why? Is it because tm_mday and tm_mon are set to 0? At first I tried not to initialize everything to zero, but then mktime returned -1. What should I do differently if I only know the year, and not the month and month?

+6
source share
1 answer

mktime() does what it should do.

Citation of the standard C:

The mktime function converts the staking time, expressed as local time, in the structure pointed to by timeptr into a time value calendar with the same encoding as the values ​​returned by time . The initial values ​​of tm_wday and tm_yday components of the structure are ignored, and the initial values ​​of other components are not limited to the ranges indicated above. Upon successful completion, the values ​​of tm_wday and tm_yday are structure components set accordingly, and the remaining components are configured to represent the specified calendar time, but with their values ​​supplanted by the ranges indicated above; The final value of tm_mdayis is not set before tm_mon and tm_year .

mktime() can compute tm_mday and tm_yday from other members; it is not intended to calculate the values ​​of other members from these fields.

However, you can initialize struct tm with values ​​out of range. For example, if you want tm_yday be 200 (the 200th day of the year), you can initialize a struct tm representing the 200th day of January. mktime() then normalizes it to the desired date, getting the time_t value, which you can pass to gmtime() or localtime() .

Here is a simple example:

 #include <iostream> #include <ctime> int main() { struct tm t = { 0 }; t.tm_sec = t.tm_min = t.tm_hour = 0; // midnight t.tm_mon = 0; // January t.tm_year = 2012 - 1900; t.tm_isdst = -1; // unknown t.tm_mday = 200; // January 200th? time_t when = mktime(&t); const struct tm *norm = localtime(&when); // Normalized time std::cout << "month=" << norm->tm_mon << ", day=" << norm->tm_mday << "\n"; std::cout << "The 200th day of 2012 starts " << asctime(norm); } 

Conclusion:

 month=6, day=18 The 200th day of 2012 starts Wed Jul 18 00:00:00 2012 
+14
source

Source: https://habr.com/ru/post/910036/


All Articles