1 // Copyright 2020 The Chromium Authors
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 #include "net/third_party/quiche/overrides/quiche_platform_impl/quiche_time_utils_impl.h"
6 
7 #include "third_party/boringssl/src/include/openssl/time.h"
8 
9 #include <iostream>
10 
11 namespace quiche {
12 
QuicheUtcDateTimeToUnixSecondsImpl(int year,int month,int day,int hour,int minute,int second)13 std::optional<int64_t> QuicheUtcDateTimeToUnixSecondsImpl(int year,
14                                                           int month,
15                                                           int day,
16                                                           int hour,
17                                                           int minute,
18                                                           int second) {
19   struct tm tmp_tm;
20   tmp_tm.tm_year = year - 1900;
21   tmp_tm.tm_mon = month - 1;
22   tmp_tm.tm_mday = day;
23   tmp_tm.tm_hour = hour;
24   tmp_tm.tm_min = minute;
25   tmp_tm.tm_sec = second;
26   // BoringSSL POSIX time, like POSIX itself, does not support leap seconds.
27   bool leap_second = false;
28   if (tmp_tm.tm_sec == 60) {
29     tmp_tm.tm_sec = 59;
30     leap_second = true;
31   }
32   int64_t result;
33   if (!OPENSSL_tm_to_posix(&tmp_tm, &result)) {
34     return std::nullopt;
35   }
36   // Our desired behaviour is to return the following second for a leap second
37   // assuming it is a valid time.
38   if (leap_second) {
39     if (!OPENSSL_posix_to_tm(result + 1, &tmp_tm)) {
40       return std::nullopt;
41     }
42     result++;
43   }
44   return result;
45 }
46 
47 }  // namespace quiche
48