From: Markus Rathgeb <maggu2810@gmail.com>
To: libstdc++@gcc.gnu.org
Subject: std::get_time changed
Date: Mon, 7 Mar 2022 08:44:50 +0100 [thread overview]
Message-ID: <CAOcK=COLnbZM1r+DqX4q6_eH2wFt707NPcXE390uVirs5bRWWA@mail.gmail.com> (raw)
Hello,
I realized a changed behavior of the function "std::get_time" with respect
to tm_wday and tm_yday.
In older versions tm_wday and tm_yday has not been modified. In more recent
version it is modified and set to the correct value (similar to strptime).
IMHO the "new" behavior is more consistent but I wonder what is "correct"
or expected.
Having a look at https://en.cppreference.com/w/cpp/io/manip/get_time the
fields tm_wday and tm_ydas are set by only a few conversion specifiers.
Can you give me some details about the changed behavior and where it is
documented.
== Versions used ==
Fedora 36
rpm -qi glibc
Name : glibc
Version : 2.35
Release : 3.fc36
rpm -qi gcc-c++
Name : gcc-c++
Version : 12.0.1
Release : 0.9.fc36
Ubuntu Focal
apt info libc6
Package: libc6
Version: 2.31-0ubuntu9
apt info g++
Package: g++
Version: 4:9.3.0-1ubuntu2
== Code Exmaple output for Ubuntu Focal and Fedora 36 ==
Initialize struct tm with 0x00
Ubuntu Focal - std::get_time | sec: 58, min: 24, hour: 7, mday: 16, mon: 5,
year: 121, wday: 0, yday: 0, isdst: 0, tm_gmtoff: 0, skipped: tm_zone
Ubuntu Focal - strptime | sec: 58, min: 24, hour: 7, mday: 16, mon: 5,
year: 121, wday: 3, yday: 166, isdst: 0, tm_gmtoff: 0, skipped: tm_zone
Fedora 36 - std::get_time | sec: 58, min: 24, hour: 7, mday: 16, mon: 5,
year: 121, wday: 3, yday: 166, isdst: 0, tm_gmtoff: 0, skipped: tm_zone
Fedora 36 - strptime | sec: 58, min: 24, hour: 7, mday: 16, mon: 5,
year: 121, wday: 3, yday: 166, isdst: 0, tm_gmtoff: 0, skipped: tm_zone
Initialize struct tm with 0x01
Ubuntu Focal - std::get_time | sec: 58, min: 24, hour: 7, mday: 16, mon: 5,
year: 121, wday: 16843009, yday: 16843009, isdst: 16843009, tm_gmtoff:
72340172838076673, skipped: tm_zone
Ubuntu Focal - strptime | sec: 58, min: 24, hour: 7, mday: 16, mon: 5,
year: 121, wday: 3, yday: 166, isdst: 16843009, tm_gmtoff:
72340172838076673, skipped: tm_zone
Fedora 36 - std::get_time | sec: 58, min: 24, hour: 7, mday: 16, mon: 5,
year: 121, wday: 3, yday: 166, isdst: 16843009, tm_gmtoff:
72340172838076673, skipped: tm_zone
Fedora 36 - strptime | sec: 58, min: 24, hour: 7, mday: 16, mon: 5,
year: 121, wday: 3, yday: 166, isdst: 16843009, tm_gmtoff:
72340172838076673, skipped: tm_zone
Initialize struct tm with 0xFF
Ubuntu Focal - std::get_time | sec: 58, min: 24, hour: 7, mday: 16, mon: 5,
year: 121, wday: -1, yday: -1, isdst: -1, tm_gmtoff: -1, skipped: tm_zone
Ubuntu Focal - strptime | sec: 58, min: 24, hour: 7, mday: 16, mon: 5,
year: 121, wday: 3, yday: 166, isdst: -1, tm_gmtoff: -1, skipped: tm_zone
Fedora 36 - std::get_time | sec: 58, min: 24, hour: 7, mday: 16, mon: 5,
year: 121, wday: 3, yday: 166, isdst: -1, tm_gmtoff: -1, skipped: tm_zone
Fedora 36 - strptime | sec: 58, min: 24, hour: 7, mday: 16, mon: 5,
year: 121, wday: 3, yday: 166, isdst: -1, tm_gmtoff: -1, skipped: tm_zone
== Code Example ==
#include <iostream>
#include <cstring>
#include <ctime>
#include <iomanip>
#include <list>
#include <sstream>
#include <string>
namespace {
constexpr const char *k_defaultTimeFormat = "%Y-%m-%d %H:%M:%S";
bool parseGetTime(std::tm *tm, std::string time, std::string format) {
std::istringstream iss(time);
iss >> std::get_time(tm, format.c_str());
return !iss.fail();
}
bool parseStrptime(std::tm *tm, const char *time, const char *format) {
const char *rv = strptime(time, format, tm);
if (rv == nullptr) {
return false;
}
return *rv == '\0';
}
void printTm(const std::tm &tm) {
std::printf("sec: %d, min: %d, hour: %d, mday: %d, mon: %d, year:
%d, wday: %d, yday: %d, isdst: %d, tm_gmtoff: %ld, skipped: tm_zone\n",
tm.tm_sec, tm.tm_min, tm.tm_hour, tm.tm_mday,
tm.tm_mon, tm.tm_year, tm.tm_wday, tm.tm_yday, tm.tm_isdst, tm.tm_gmtoff
/*, tm.tm_zone*/);
}
}// namespace
int main() {
struct tm tm;
constexpr const char *timestr = "2021-06-16 07:24:58";
for (const int r: std::list<int>{0x00, 0x01, 0xFF}) {
std::memset(&tm, r, sizeof(tm));
if (parseGetTime(&tm, timestr, k_defaultTimeFormat)) {
printTm(tm);
} else {
std::cerr << "parsing failure: get time" << std::endl;
}
std::memset(&tm, r, sizeof(tm));
if (parseStrptime(&tm, timestr, k_defaultTimeFormat)) {
printTm(tm);
} else {
std::cerr << "parsing failure: strptime" << std::endl;
}
}
return 0;
}
next reply other threads:[~2022-03-07 7:45 UTC|newest]
Thread overview: 2+ messages / expand[flat|nested] mbox.gz Atom feed top
2022-03-07 7:44 Markus Rathgeb [this message]
2022-03-07 11:51 ` Jonathan Wakely
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to='CAOcK=COLnbZM1r+DqX4q6_eH2wFt707NPcXE390uVirs5bRWWA@mail.gmail.com' \
--to=maggu2810@gmail.com \
--cc=libstdc++@gcc.gnu.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).