【问题标题】:Generically getting the date and time一般获取日期和时间
【发布时间】:2019-02-20 05:54:36
【问题描述】:

我知道这个问题之前可能已经被问过,但这是我之前在here 找到的问题之一的后续。与其他问题相比,这个问题的独特之处在于我正在寻找与我的编译器相关的最新内容:Visual Studio 2017 using C++17 - latest draft standard。

我知道 C++20 将及时发布并可用于我期待的 Visual Studio 2019。但是目前;我仍在 Windows 7 上使用 Visual Studio 2017,并且目前仅限于 C++17。我发现这个Q/A 与提供了很好答案的这个类似,但是当我开始使用<ctime><time.h> 函数时,例如:

std::gmtime()
std::localtime()

我的编译器对我大喊,这些函数被标记为不安全且已弃用。我试图写一个这样的函数:

-DateAndTime.h-

#pragma once

#include <ctime>
#include <iomanip>
#include <iostream>
#include <sstream>  

namespace util {

    enum class TimeLocale {
        LOCAL = 0x01,
        GMT   = 0x02,
        BOTH = (LOCAL | GMT)
    };

    inline TimeLocale operator|(TimeLocale a, TimeLocale b) {
        return static_cast<TimeLocale>(static_cast<int>(a) | static_cast<int>(b)); 
    }

#pragma warning( push )
#pragma warning( disable : 4996 )
    inline void currentDateAndTime(std::stringstream& stream, TimeLocale locale) {
        std::time_t t = std::time(nullptr);

        if (locale == TimeLocale::GMT) {
            stream << "UTC:   " << std::put_time( std::gmtime(&t), "%c, %Z") << '\n';
        }

        if (locale == TimeLocale::LOCAL) {
            stream << "LOCAL: " << std::put_time(std::localtime(&t), "%c, %Z") << '\n';
        }

        if (locale == TimeLocale::BOTH) {
            stream << "UTC:   " << std::put_time(std::gmtime(&t), "%c, %Z") << '\n'
                   << "LOCAL: " << std::put_time(std::localtime(&t), "%c, %Z") << '\n';
        }
    }
#pragma warning( pop )

} // namespace util

-main.cpp-

#include "DateAndTime.h"

#include <iostream>
#include <sstream>

using namespace util;

int main() {
    try {
        std::stringstream stream1;
        getCurrentTime(stream1, TimeLocale::GMT);
        std::cout << stream1.str() << '\n';

        std::stringstream stream2;
        getCurrentTime(stream2, TimeLocale::LOCAL);
        std::cout << stream2.str() << '\n';

        std::stringstream stream3;
        getCurrentTime(stream3, TimeLocale::BOTH);
        std::cout << stream3.str() << '\n';

        std::stringstream stream4;
        getCurrentTime(stream4, TimeLocale::GMT | TimeLocale::LOCAL);
        std::cout << stream4.str() << '\n';         

    // ExceptionHandler is one of my class's and can be ignored in this context
    // You can replace this with std::exception, std::cerr, etc...
    } catch ( ExceptionHandler& e ) {
        std::cout << "Exception Thrown: " << e.getMessage() << std::endl;
        return EXIT_FAILURE;
    } catch (...) {
        std::cout << __FUNCTION__ << " Caught Unknown Exception" << std::endl;
        return EXIT_FAILURE;
    }
    return EXIT_SUCCESS;
}

如果我使用#pragma warning( disable : 4996 ),这很好用

我得到了这样一个不错的输出:

UTC:   02/20/19 05:44:38, Eastern Standard Time

Local: 02/20/19 00:44:38, Eastern Standard Time

UTC:   02/20/19 05:44:38, Eastern Standard Time
Local: 02/20/19 00:44:38, Eastern Standard Time

UTC:   02/20/19 05:44:38, Eastern Standard Time
Local: 02/20/19 00:44:38, Eastern Standard Time

这看起来很棒。但是,我宁愿不使用任何标记为已弃用、不是特定于平台、通用、可移植和跨平台的函数,这些函数目前在 C++17 中可用。最好是标准库中的东西。我不想使用第三方库也不想提升。 std::chrono 将是一个不错的选择,但是它们的 calendar 部分将在 C++20 的完整版本之前不可用。我还有哪些选择?

【问题讨论】:

    标签: datetime cross-platform std c++17 c++-standard-library


    【解决方案1】:

    函数 gmtime 和 localtime 没有被弃用。

    仅对于 Visual Studio,它们已被弃用,因为 Visual Studio 提供了替代的 gmtime_s 和 localtime_s,所以我会使用这些函数。 在 Unix 下,如果你想成为线程安全的,你有 gmtime_r 和 localtime_r。另见this answer

    在 Windows 下编写一个内联的 gmtime_r 和 localtime_r 调用 gmtime_s 和 localtime_s,你就有了一个几乎标准的跨平台解决方案,直到 C++20。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2013-12-13
      • 1970-01-01
      • 1970-01-01
      • 2017-12-01
      • 2012-12-04
      • 2016-11-06
      • 2017-02-20
      相关资源
      最近更新 更多