加减时间

问题描述 投票:0回答:6

我是 C++ 新手 - 我想编写一个程序来使用 HH:MM 格式添加和减去时间。输入示例:

12:00 + 3:00 - 6:00

示例输出:

9:00

另一个示例输入:

9:00 + 8:00 + 13:00 - 2:25

示例输出:

27:35

我怎么知道这个?我正在考虑将所有内容转换为秒,然后应用数学,然后使用模数 60 函数返回时间。对构建这样的程序有帮助吗?

c++ time
6个回答
3
投票

您需要考虑“时间”的含义。有两个概念,时间点和持续时间。将时间点加在一起没有任何意义。添加和减去持续时间(产生持续时间)确实有意义,并且用时间点添加和减去持续时间(产生相对于原始时间点的新时间点偏移)确实有意义。从一个时间点减去另一个时间点,产生中间持续时间也是有意义的。

很多时候 API 并不能很好地区分这两个概念,但标准 C++

<chrono>
库却可以。

这里有一些代码滥用 C

tm
类型,以便从用户那里获取几个持续时间,将它们加在一起,然后再次滥用
tm
来输出结果。

#include <iostream> // cout, cin
#include <iomanip>  // get_time, put_time
#include <chrono>   // hours, minutes, duration_cast

int main() {
    // input, get a couple durations to do arithmetic on
    // technically std::tm represents a time point and get_time is supposed to
    // parse a time point, but we treat the results as a duration
    std::tm t;
    std::cin >> std::get_time(&t, "%H:%M");

    auto duration1 = std::chrono::hours(t.tm_hour) + std::chrono::minutes(t.tm_min);

    std::cin >> std::get_time(&t, "%H:%M");
    auto duration2 = std::chrono::hours(t.tm_hour) + std::chrono::minutes(t.tm_min);

    // do the arithmetic
    auto sum = duration1 + duration2;

    // output
    auto hours   = std::chrono::duration_cast<std::chrono::hours>(sum);
    auto minutes = std::chrono::duration_cast<std::chrono::minutes>(sum - hours);

    t.tm_hour = hours.count();
    t.tm_min  = minutes.count();

    std::cout << std::put_time(&t, "%H:%M") << '\n';
}

2
投票

作为 C++ 新手,我想分享一些代码作为问题要求的程序。这不是完美的代码,但对于 C++ 新手来说可能是一个很好的实践机会。它将解决时间戳的加法和减法问题。即您可能需要添加额外的验证,并且可以扩展到表示天、秒和毫秒...

#include <iostream>
#include <string>

using namespace std;

/// Represents the timestamp in HH:MM format
class Time {
public:
    // Construct the time with hours and minutes
    Time(size_t hours, size_t mins);

    // Construct the time using a string
    Time(const string& str);

    // Destructor
    ~Time() {}

    // Add a given time
    Time operator + (const Time& rTime) const;

    // Subtract a given time
    Time operator - (const Time& rTime) const;

    // Get the members
    int Hours() const { return m_Hours; }
    int Minutes() const { return m_Minutes; }

    // Get the time as a string in HH:MM format
    string TimeStr();   

private:
    // Private members
    int m_Hours;    // Hours
    int m_Minutes;  // Minutes
};

// Constructor
Time::Time(size_t hours, size_t mins) {
    if (hours >= 60 || mins >= 60) {
        cout << "Invalid input" << endl;    
        exit(0);
    }

    // Update the members
    m_Hours = hours;
    m_Minutes = mins;
}

// Add the given time to this
Time Time::operator + (const Time& rTime) const {
    // Construct the time
    int nTotalMinutes(m_Minutes + rTime.Minutes());
    int nMinutes(nTotalMinutes % 60);
    int nHours(nTotalMinutes/60 + (m_Hours + rTime.Hours()));

    // Return the constructed time
    return Time(nHours, nMinutes);
}

// Construct the time using a string
Time::Time(const string& str) {
    if(str.length() != 5 || str[2] != ':') {
        cout << "Invalid time string. Expected format [HH:MM]" << endl;
        exit(0);
    }

    // Update the members
    m_Hours  = stoi(str.substr(0, 2));  
    m_Minutes = stoi(str.substr(3, 2)); 
}

// Substact the given time from this
Time Time::operator - (const Time& rTime) const {
    // Get the diff in seconds
    int nDiff(m_Hours*3600 + m_Minutes*60 - (rTime.Hours()*3600 + rTime.Minutes()*60));

    int nHours(nDiff/3600);
    int nMins((nDiff%3600)/60);

    // Return the constructed time
    return Time(nHours, nMins);
}

// Get the time in "HH:MM" format
string Time::TimeStr() {
    // Fill with a leading 0 if HH/MM are in single digits
    return ((m_Hours < 10) ? string("0") + to_string(m_Hours) : to_string(m_Hours))
           + string(":")
           + ((m_Minutes < 10) ? string("0") + to_string(m_Minutes) : to_string(m_Minutes));
}


int main() {
    Time time1("09:00");    // Time 1
    Time time2("08:00");    // Time 2
    Time time3("13:00");    // Time 3
    Time time4("02:25");    // Time 4

    //time1 + time 2 + time3 - time4
    cout << (time1 + time2 + time3 - time4).TimeStr() << endl;

    return 0;
}

输出: 27:35


1
投票

this(第 1 部分)和 this(第 2 部分)应该正是您想要的..

您会得到清晰的解释,作者逐行逐步执行代码,并且他还使用了最佳实践。


0
投票

最简单的解决方案是将输入解析为整数(使用

std::istream
),将它们插入
tm
(在
<time.h>
中定义的类型),然后调用
mktime
(也在
<time.h>
中)。 (C++11 中有一些处理时间的新东西,但我还不太熟悉它。)


0
投票

我发现这一行有一个小问题:

int nDiff(m_Hours*3600 + m_Minutes*60 - (rTime.Hours()*3600 + rTime.Minutes()*60));

在 nDiff( ... ) 中,参数必须是绝对值! nDiff( 绝对 (...) )

当你有例如:

Time time1("01:00");
Time time2("02:00");
cout << ( time1 - time2 ).TimeStr() << endl;

输出:

hours = 18446744073709551615
Invalid input

对于案例:

cout << ( time1 + time2 ).TimeStr() << endl;

输出:

03:00

这个结论只是改变:

int nDiff(m_Hours*3600 + m_Minutes*60 - (rTime.Hours()*3600 + rTime.Minutes()*60));

对于这个:

int nDiff( abs(m_Hours*3600 + m_Minutes*60 - (rTime.Hours()*3600 + rTime.Minutes()*60) ) );

并将其添加到代码中的标题中:

#include <cstdlib> // function abs()

这样代码就可以很好的运行了。 :)

编码愉快! 干杯。


0
投票

使用计时。我很惊讶用它可以轻松完成很多事情。 https://www.youtube.com/watch?v=P32hvk8b13M

© www.soinside.com 2019 - 2024. All rights reserved.