Create the portability header for time.h
[folly.git] / folly / portability / Time.cpp
1 /*
2  * Copyright 2016 Facebook, Inc.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *   http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16
17 #include <folly/portability/Time.h>
18
19 #ifdef _WIN32
20 #include <iomanip>
21 #include <sstream>
22
23 #include <Windows.h>
24
25 extern "C" {
26 char* asctime_r(const tm* tm, char* buf) {
27   char tmpBuf[64];
28   if (asctime_s(tmpBuf, tm)) {
29     return nullptr;
30   }
31   // Nothing we can do if the buff is to small :(
32   return strcpy(buf, tmpBuf);
33 }
34
35 char* ctime_r(const time_t* t, char* buf) {
36   char tmpBuf[64];
37   if (ctime_s(tmpBuf, t)) {
38     return nullptr;
39   }
40   // Nothing we can do if the buff is to small :(
41   return strcpy(buf, tmpBuf);
42 }
43
44 tm* gmtime_r(const time_t* t, tm* res) {
45   if (!gmtime_s(res, t)) {
46     return res;
47   }
48   return nullptr;
49 }
50
51 tm* localtime_r(const time_t* t, tm* o) {
52   if (!localtime_s(o, t)) {
53     return o;
54   }
55   return nullptr;
56 }
57
58 int nanosleep(const struct timespec* request, struct timespec* remain) {
59   Sleep((DWORD)((request->tv_sec * 1000) + (request->tv_nsec / 1000000));
60   remain->tv_nsec = 0;
61   remain->tv_sec = 0;
62   return 0;
63 }
64
65 char* strptime(const char* __restrict s,
66                const char* __restrict f,
67                struct tm* __restrict tm) {
68   // Isn't the C++ standard lib nice? std::get_time is defined such that its
69   // format parameters are the exact same as strptime. Of course, we have to
70   // create a string stream first, and imbue it with the current C locale, and
71   // we also have to make sure we return the right things if it fails, or
72   // if it succeeds, but this is still far simpler an implementation than any
73   // of the versions in any of the C standard libraries.
74   std::istringstream input(s);
75   input.imbue(std::locale(setlocale(LC_ALL, nullptr)));
76   input >> std::get_time(tm, f);
77   if (input.fail()) {
78     return nullptr;
79   }
80   return const_cast<char*>(s + input.tellg());
81 }
82 }
83 #endif