From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [170.10.129.124]) by sourceware.org (Postfix) with ESMTPS id B0F56385E036 for ; Sat, 9 Mar 2024 00:29:57 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org B0F56385E036 Authentication-Results: sourceware.org; dmarc=pass (p=none dis=none) header.from=redhat.com Authentication-Results: sourceware.org; spf=pass smtp.mailfrom=redhat.com ARC-Filter: OpenARC Filter v1.0.0 sourceware.org B0F56385E036 Authentication-Results: server2.sourceware.org; arc=none smtp.remote-ip=170.10.129.124 ARC-Seal: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1709944199; cv=none; b=Tar/XNKev7+2gl9mbHSjybO/7HboBk9cMat5Y361Mq1pAd9BVRbPc45Eo8qzqsXmeOhPlZ5aGvs+m6pMrOeff5HMDqAQ5w5g9ixh7XjBCPlnwEc924kHhbJbTppSS6JE9vJKL/lfG/Y4WD72APfxoN8e4jOEK/LZP21mOR+Q7Jo= ARC-Message-Signature: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1709944199; c=relaxed/simple; bh=RfeG63pbh/xyPKzi0TFFGlPNTYSDLgcUvxFGzvo9JGE=; h=DKIM-Signature:From:To:Subject:Date:Message-ID:MIME-Version; b=cZsa8IYFG+8KtnQcVsiZAQr5xjnkO+9/bmvX3uj+y2aR5tBVrCJghN/w98ODUP9Uq3YEbZVzz1w5K+jwLeQ+f5r+r90yFyCRPE5Tgp6F2m5aK4untmTr88DfKuRTc87FwC6YWESqoEGJRzn6NsraTQXwlY6+adrxznTqpmTqLBE= ARC-Authentication-Results: i=1; server2.sourceware.org DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1709944197; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding; bh=BMKvPgL7uc8yv4hfIn+HozX9mxBdDHQfHFcNb9oQk+8=; b=OaJgRzPoDqkJEZ6DRywE4ihPk3g62JhduYXcvAggKkmc9Db+QSGbsF+9vsJ6q2Inww1naj wSF4nf5cF4cits6mO7xMFTKbj5yjFrnNnNvAF6pLD+2xqWPgi2gtzwzsT3jU9XlxxayT4d 9+PIKmqp4aG/4YxRr9tM9IPeMidRAh0= Received: from mimecast-mx02.redhat.com (mimecast-mx02.redhat.com [66.187.233.88]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-381-TilvJpo8NFOARbHdTGL9OA-1; Fri, 08 Mar 2024 19:29:55 -0500 X-MC-Unique: TilvJpo8NFOARbHdTGL9OA-1 Received: from smtp.corp.redhat.com (int-mx03.intmail.prod.int.rdu2.redhat.com [10.11.54.3]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by mimecast-mx02.redhat.com (Postfix) with ESMTPS id 7C6418007A2; Sat, 9 Mar 2024 00:29:55 +0000 (UTC) Received: from localhost (unknown [10.42.28.8]) by smtp.corp.redhat.com (Postfix) with ESMTP id 48D0A111D640; Sat, 9 Mar 2024 00:29:55 +0000 (UTC) From: Jonathan Wakely To: libstdc++@gcc.gnu.org, gcc-patches@gcc.gnu.org Subject: [committed] libstdc++: Do not require a time-of-day when parsing sys_days [PR114240] Date: Sat, 9 Mar 2024 00:29:43 +0000 Message-ID: <20240309002954.905104-1-jwakely@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 3.4.1 on 10.11.54.3 X-Mimecast-Spam-Score: 0 X-Mimecast-Originator: redhat.com Content-Type: text/plain Content-Transfer-Encoding: 8bit X-Spam-Status: No, score=-12.1 required=5.0 tests=BAYES_00,DKIMWL_WL_HIGH,DKIM_SIGNED,DKIM_VALID,DKIM_VALID_AU,DKIM_VALID_EF,GIT_PATCH_0,RCVD_IN_DNSWL_NONE,SPF_HELO_NONE,SPF_NONE,TXREP,T_SCC_BODY_TEXT_LINE,URI_HEX autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on server2.sourceware.org List-Id: Tested x86_64-linux. Pushed to trunk. -- >8 -- When parsing a std::chrono::sys_days (or a sys_time with an even longer period) we should not require a time-of-day to be present in the input, because we can't represent that in the result type anyway. Rather than trying to decide which specializations should require a time-of-date and which should not, follow the direction of Howard Hinnant's date library, which allows extracting a sys_time of any period from input that only contains a date, defaulting the time-of-day part to 00:00:00. This seems consistent with the intent of the standard, which says it's an error "If the parse fails to decode a valid date" (i.e., it doesn't care about decoding a valid time, only a date). libstdc++-v3/ChangeLog: PR libstdc++/114240 * include/bits/chrono_io.h (_Parser::operator()): Assume hours(0) for a time_point, so that a time is not required to be present. * testsuite/std/time/parse/114240.cc: New test. --- libstdc++-v3/include/bits/chrono_io.h | 12 ++++++- .../testsuite/std/time/parse/114240.cc | 36 +++++++++++++++++++ 2 files changed, 47 insertions(+), 1 deletion(-) create mode 100644 libstdc++-v3/testsuite/std/time/parse/114240.cc diff --git a/libstdc++-v3/include/bits/chrono_io.h b/libstdc++-v3/include/bits/chrono_io.h index eaa36b8a074..b9eb3d2be53 100644 --- a/libstdc++-v3/include/bits/chrono_io.h +++ b/libstdc++-v3/include/bits/chrono_io.h @@ -3157,6 +3157,16 @@ namespace __detail minutes __tz_offset = __bad_min; basic_string<_CharT, _Traits> __tz_abbr; + if ((_M_need & _ChronoParts::_TimeOfDay) + && (_M_need & _ChronoParts::_Year)) + { + // For time_points assume "00:00:00" is implicitly present, + // so we don't fail to parse if it's not (PR libstdc++/114240). + // We will still fail to parse if there's no year+month+day. + __h = hours(0); + __parts = _ChronoParts::_TimeOfDay; + } + // bool __is_neg = false; // TODO: how is this handled for parsing? _CharT __mod{}; // One of 'E' or 'O' or nul. @@ -4098,7 +4108,7 @@ namespace __detail const bool __need_wday = _M_need & _ChronoParts::_Weekday; // Whether the caller wants _M_sys_days and _M_time. - // Only true for time_points. + // Only true for durations and time_points. const bool __need_time = _M_need & _ChronoParts::_TimeOfDay; if (__need_wday && __wday != __bad_wday) diff --git a/libstdc++-v3/testsuite/std/time/parse/114240.cc b/libstdc++-v3/testsuite/std/time/parse/114240.cc new file mode 100644 index 00000000000..46310efd09a --- /dev/null +++ b/libstdc++-v3/testsuite/std/time/parse/114240.cc @@ -0,0 +1,36 @@ +// { dg-do run { target c++20 } } + +// PR libstdc++/114240 sys_days not being parsed with only a date in the stream + +#include +#include +#include + +template +void +test_parse_date_only() +{ + using namespace std::chrono; + + using CDays = time_point; + CDays td; + std::istringstream is("2024-03-05"); + VERIFY( is >> parse("%Y-%m-%d ", td) ); + if constexpr (std::is_same_v) + VERIFY( td == static_cast>(2024y/March/5) ); + else + { + auto tp = clock_cast(sys_days(2024y/March/5)); + VERIFY( td == time_point_cast(tp) ); + } +} + +int main() +{ + test_parse_date_only(); + test_parse_date_only(); + test_parse_date_only(); + test_parse_date_only(); + test_parse_date_only(); + test_parse_date_only(); +} -- 2.43.2