【问题标题】:Convert `time_t` to decimal year in C++在 C++ 中将 `time_t` 转换为十进制年份
【发布时间】:2015-11-10 01:54:54
【问题描述】:

如何将time_t 结构转换为十进制年份?

例如,对于日期2015-07-18 00:00:00,我想得到2015.625

【问题讨论】:

  • 你能描述一下你是如何获得.625的吗?据谷歌称,这是一年中的第 199 天,199/365 = 0.545

标签: c++ date time time-t


【解决方案1】:

根据我的评论寻求更多关于您如何来到.625 的信息,我假设您实际上是指.55,因为 2015 年 7 月 18 日是一年中的第 199 天。

您需要首先使用get_time 将时间从字符串获取到std::tm 结构中。然后,在mktime 的帮助下,我们应该能够得到一年中的某一天。然后,我们可以快速计算一下年份是否是闰年,然后进行除法得到我们的比率:

完整代码

Live Demo

包括

#include <ctime>
#include <iostream>
#include <sstream>
#include <locale>
#include <iomanip>
#include <string.h>

主要

int main()
{
    std::tm theTime = {};
    

正确调用 get_time

    // initialize timeToConvert with the Year-Month-Day Hours:Minutes:Seconds string you want
    std::string timeToConvert = "2015-07-18 00:00:00";
    std::istringstream timeStream(timeToConvert);
    
    // need to use your locale (en-US)
    timeStream.imbue(std::locale("en_US.UTF-8"));
    timeStream >> std::get_time(&theTime, "%Y-%m-%d %H:%M:%S");
    if (timeStream.fail()) 
    {
        std::cerr << "Parse failed\n";
        exit(0);
    } 

mktime

    // call mktime to fill out other files in theTime
    std::mktime(&theTime);
    

获取一年中的某一天和一年中的天数

    // get years since 1900
    int year = theTime.tm_year + 1900;
    
    /* determine if year is leap year:
    If the year is evenly divisible by 4, go to step 2. ...
    If the year is evenly divisible by 100, go to step 3. ...
    If the year is evenly divisible by 400, go to step 4. ...
    The year is a leap year (it has 366 days).
    The year is not a leap year (it has 365 days).
    */
    bool isLeapYear =  year % 4 == 0 &&
                        year % 100 == 0 &&
                        year % 400 == 0;
    
    // get number of days since January 1st
    int days = theTime.tm_yday+1; // Let January 1st be the 1st day of year, not 0th
  
    
    // get number of days in this year (either 365 or 366 if leap year)
    int daysInYear = isLeapYear ? 366 : 365;
    

最后进行除法并打印结果值

    double yearAsFloat = static_cast<double>(year) + static_cast<double>(days)/static_cast<double>(daysInYear);
    
    std::cout << timeToConvert << " is " << yearAsFloat << std::endl;
}

输出:

2015-07-18 00:00:00 是 2015.55

【讨论】:

  • memset 很傻,你刚刚正确初始化了上一行的每个成员
  • @Cubbi:你是对的。我错误地认为它是可移植代码所必需的,因为我在没有它的 VS 中看到了一个问题,但是说问题是由于没有初始化到 {} 并且没有调用 memset 来补偿引起的。我已经编辑了帖子。
【解决方案2】:

您可以使用例如将其转换为 broken down time std::gmtimestd::localtime

分解的时间结构包含年份和一个tm_yday 成员,即自1 月1 日以来的天数。您可以使用这个tm_yday 成员来计算小数点后的部分。

如果您想要更高的分辨率,也可以使用小时、分钟和秒。

【讨论】:

    【解决方案3】:

    使用 strftime

    struct stat info; 
    char buff[20]; 
    struct tm * timeinfo;
    
    stat(workingFile, &info); 
    
    timeinfo = localtime (&(info.st_mtime)); 
    strftime(buff, 20, "%b %d %H:%M", timeinfo); 
    printf("%s",buff);
    

    格式:

    %b - The abbreviated month name according to the current locale.
    
    %d - The day of the month as a decimal number (range 01 to 31).
    
    %H - The hour as a decimal number using a 24-hour clock (range 00 to 23).
    
    %M - The minute as a decimal number (range 00 to 59).
    

    【讨论】:

    • 没有输出小数年的选项,%s是什么意思?
    • %s 表示您正在打印字符串
    【解决方案4】:

    使用以下步骤:

    • 使用std::gmtime 将年月日分开。
    • 计算X = 日和月中的天数(记住年份可以是a leap year);例如,对于 2 月 3 日,X 将始终是 31 + 3 = 34; 对于 3 月 3 日,对于闰年,它将是 31 + 28 + 3 = 6231 + 29 + 3 = 63
    • 计算Y = 一年的天数
    • 使用公式计算百分比:(X * 100.) / Y 并以三位小数显示

    【讨论】:

      猜你喜欢
      • 2021-12-26
      • 2018-05-10
      • 2021-06-26
      • 1970-01-01
      • 2017-07-31
      • 2013-07-20
      • 2012-06-17
      • 2019-07-20
      • 2012-12-26
      相关资源
      最近更新 更多