【问题标题】:Convert char array representing a date to seconds since 1970将表示日期的 char 数组转换为自 1970 年以来的秒数
【发布时间】:2021-03-27 06:56:04
【问题描述】:

有很多链接可以实现这一点,但我实际上无法从接受的答案中找到代码示例(不使用 boost),最有效的方法是什么:

char date[] = "2021-01-01";
long double seconds = SecondsSince1970(date);

以及类似 10000000000 或多少秒的输出?

编辑:(由 C++ 实现)

std::tm t = {};
std::istringstream ss("2010-11-04T23:23:01Z");
if (ss >> std::get_time(&t, "%Y-%m-%dT%H:%M:%S")){
    std::cout << std::put_time(&t, "%c") << "\n"  << std::mktime(&t) << "\n";
} 

我想这个问题的一个扩展是如何复制这个 C++ 代码但不使用 istringstream 所以它不必分配内存,而是直接从原始 char [] 数组到秒?

【问题讨论】:

  • 程序是否应该假设所有年份都有 365 天?
  • 呃,我需要它与当前时间准确,所以当我转换回来时它是一样的。例如,在 python 中,我只是尝试了time.time() 并得到了1616828423.9408524 所以类似的东西
  • 这能回答你的问题吗? strtotime function in C
  • 使用strptime + mktime
  • @AnttiHaapala 我已经看到,我在 Windows 上,我无法让它工作,而且这些答案中的任何一个都没有任何关于如何使用它们的例子,只是说使用它功能。我希望能够使用char [] 来做到这一点,所以没有新的内存分配给istringstream,这可能吗?

标签: arrays c date datetime


【解决方案1】:

只需 3 个简单的步骤即可完成:

  • sscanf 字符串(奖励 - 检查有效日期)
  • 获取自 1970 年以来的日子
  • 乘以 24 * 60 * 60

#include <stdio.h>

int leap_years(int month, int year)
{
    int years = year;

    if (month <= 2)
    {
        years--;
    }
    return (years / 4) - (years / 100) + (years / 400);
}

int days_diff(int day1, int month1, int year1,
              int day2, int month2, int year2)
{
    static const int days[] = {0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334};
    long int days1 = (year1 * 365) + day1;
    long int days2 = (year2 * 365) + day2;

    days1 += days[month1 - 1] + leap_years(month1, year1);
    days2 += days[month2 - 1] + leap_years(month2, year2);
    return (int)(days2 - days1);
}

int year_isleap(int year)
{
    return (((year % 4) == 0) && ((year % 100) != 0)) || ((year % 400) == 0);
}

int month_days(int month, int year)
{
    static const int days[2][12] =
    {
        {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31},
        {31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}
    };
    int leap = year_isleap(year);

    return days[leap][month - 1];
}

int date_isvalid(int day, int month, int year)
{
    if ((year < 0) || (year > 9999))
    {
        return 0;
    }
    if ((month < 1) || (month > 12))
    {
        return 0;
    }
    if ((day < 1) || (day > month_days(month, year)))
    {
        return 0;
    }
    return 1;
}

int main(void)
{
    int d, m, y;

    if ((sscanf("2021-01-01", "%d-%d-%d", &y, &m, &d) == 3) &&
        (date_isvalid(d, m, y)))
    {
        long double seconds = days_diff(1, 1, 1970, d, m, y) * 24 * 60 *60;

        printf("%.0Lf\n", seconds);
    }
    else
    {
        puts("Wrong date");
    }
    return(0);
}

输出:

1609459200

【讨论】:

  • 抱歉,我会编辑问题。我认为您的回答非常有用,但我应该更清楚地说明。不过请留下它,我确定将来会需要它
  • @AndySukowski-Bang 从"2021-01-01"time(NULL) 获取纪元以来的秒数会有点困难?
  • 错了大卫:)(今晚他们太多了)
  • 如果没有istringstream,使用我的编辑,C++ 方式怎么样?这可能吗,我想直接从我的char [] 实现它,所以之后没有分配,直接从char [] 到秒?
  • 你能更新它,让它考虑闰年,比如 python time.time() 返回相同的结果吗?抱歉,我知道这可能有点复杂,我只需要那个时间,因为我查看了历史数据,它可能在 2 月 29 日,也可能不在,等等。我知道你放了闰年,但它的返回时间与 python/中的time.time() 不同
猜你喜欢
  • 2011-08-31
  • 1970-01-01
  • 2016-06-16
  • 2012-01-19
  • 1970-01-01
  • 2013-01-20
  • 1970-01-01
  • 1970-01-01
  • 2023-01-08
相关资源
最近更新 更多