【问题标题】:Calculate minutes until specific time? (C)计算直到特定时间的分钟数? (C)
【发布时间】:2009-10-03 22:23:51
【问题描述】:

计算直到晚上 9 点(今天或明天)的分钟数的最简单方法是什么?

正在查看 mktime() 但似乎很难获得日期 # 和月份,处理所有这些。

【问题讨论】:

    标签: c time


    【解决方案1】:

    只需计算到今天晚上 9 点的增量。如果它是负数,则添加 24 小时以使 delta 达到明天的晚上 9 点。

    #include <stdio.h>
    #include <time.h>
    
    int main(int argc, char* argv[]) {
        struct tm* tm;
        time_t ts=time(NULL);
        if(tm=localtime(&ts)) {
                long int delta;
                tm->tm_hour = 21;
                tm->tm_min = 0;
                tm->tm_sec = 0;
                delta = mktime(tm) - ts;
                if(delta<0) {
                        delta+=24*60*60;
                }
                printf("%d minutes til (next)9pm\n",delta/60);
        }
        return 0;
    }
    

    【讨论】:

    • 我已经发布了一个使用 difftime 函数的解决方案。它将确保跨各种 *nix 风格的可移植性。即使是 long int,也不会根据底层架构(x86 或 x86_64 或其他)检查“delta”
    【解决方案2】:

    这将为您提供直到晚上 9 点的分钟数。:

    time_t currenttime;
    time_t ninePM;
    struct tm * timeinfo;
    int minutesUntilNine;
    
    // Fill currenttime + convert to struct tm
    time ( &currenttime );
    timeinfo = localtime ( &rawtime );
    
    // Check for after 9pm...
    if (timeinfo->tm_hour >= 21) // Are we after 9pm?
      timeinfo->tm_day++; // increment our day
    
    // Set timeinfo to the time you want...
    timeinfo->tm_sec = 0;
    timeinfo->tm_min = 0;
    timeinfo->tm_hour = 21; // 9pm
    ninePM = mktime( timeinfo );
    
    minutesUntilNine = (ninePM - currenttime) / 60;
    

    【讨论】:

    • 羞于看到一个好的答案标志着最糟糕的。 Reed,我认为您还需要在增加日期时将 isdst 设置为 -1。这将确保如果夏令时在同一时间开始或结束,您将获得晚上 9 点。在夏令时转换时,大多数其他答案都是错误的,因为在那一天,每天的秒数不是 24 * 60 * 60。@ZZambia,mktime() 规范了结构的字段。例如 1 月 32 日 -> 2 月 1 日。
    【解决方案3】:

    一个简单的方法是计算小时数和分钟数(给定现在的时间,加上一天有 24 小时的事实),然后将小时数乘以 60,使其成为分钟。或者,不要使用 24 小时制来表示时间,而是使用 1440 分钟制:很容易将一个时间减去另一个时间,得到一个时差。

    【讨论】:

      【解决方案4】:

      在这里(以秒为单位输出...)

      #include <stdio.h>
      #include <time.h>
      
      int main(void) 
      {
        double dt = 0.0f;
        time_t ti = time(NULL);
        time_t tf;
        struct tm *pt_actual = localtime(&ti);
      
        struct tm t_actual = *pt_actual;
        struct tm t_target = *pt_actual;
      
        t_target.tm_hour = 21; // 09:00 pm
        t_target.tm_min = 0;
      
        tf = mktime(&t_target);
      
        dt = difftime(tf, ti);
        if (dt < 0)
          dt += (24*60*60);  // if negative, just consider **next** 9pm target, add a day
      
        printf("difftime = %f seconds\n", dt );
        return 0;
      }
      

      【讨论】:

        【解决方案5】:

        这家伙要求最简单的方法。你所有的方式都是不必要的复杂。只需使用模算术:

        #include <stdio.h>
        #include <time.h>
        
        #define TARGET_TIME 21*60 // 9:00 PM, in format HH * 60 + MM
        
        int main(int argc, char* argv[])
        {
            struct tm* tm;
            time_t ts = time(NULL);
            int minutes_until_9pm;
            tm = localtime(&ts);
            minutes_until_9pm = 24*60 - (tm->tm_min + tm->tm_hour * 60 + TARGET_TIME)%(24*60);
        
            //alternatively, the following is slightly faster
            //minutes_until_9pm = 24*60 - (tm->tm_min + tm->tm_hour * 60 + TARGET_TIME) + (tm->tm_min+tm->tm_hour*60+TARGET_TIME>24*60?24*60:0);
        
            printf("%d minutes til (next)9pm\n", minutes_until_9pm);
            return 0;
        }
        

        如果你知道你的时区,一切都会变得更简单:

        #include <stdio.h>
        #include <time.h>
        
        #define TARGET_TIME 21*60 // 9:00 PM, in format HH * 60 + MM
        #define TIMEZONE (-6) // This is CST; replace with your own timezone
        
        int main(int argc, char* argv[])
        {
            int minutes_until_9pm = 24*60 - (time(NULL)/60 + TARGET_TIME + (24+TIMEZONE)*60)%(24*60);
            printf("%d minutes til (next)9pm\n", minutes_until_9pm);
            return 0;
        }
        

        这里发生的情况是,以一天为模,我们得到自午夜以来的分钟数。然后我们添加 9:00 PM 以获取自 9:00 PM 以来的分钟数。然后我们从 24 小时中减去它,得到下一个晚上 9:00 之前的分钟数。

        如果您需要更高的准确度(即四舍五入到最接近的分钟数,而不是简单的分钟数),只需从minutes_until_9pm 中减去(tm-&gt;tm_sec&gt;=30?0:1),或将time(NULL)/60 分别替换为(time(NULL)+30)/60

        【讨论】:

        • 真的很简单......遗憾的是,“time(NULL)/60”会提供 59 次机会来获得坏结果,从而导致结果被截断。此外,你有没有找过 (21*60) 余数的 asm 代码??!?!如果为负,则总和对于糟糕的编译器来说要容易得多,并且在 any C 风格上更具可移植性。
        • 好吧,你表现得好像其他解决方案没有截断问题。他们是这样。我已经添加了让它们四舍五入的说明,但总的来说,这没什么大不了的。 (21*60) 是一个错字,我的意思是 (24*60)。当然,性能不是很好,但它并不比任何其他计算方法差,例如localtime(),这是其他人正在使用的。不过,我将优化第一个点头以使用模算术。
        • 此外,考虑到localtime() 比单个模数要慢,我怀疑这种差异是否有意义。
        • 但是我们正在将苹果与梨进行比较......如果您想忽略您的时区,则需要 localtime(),在其他情况下不需要(已知 TZ,如您的示例)。供您参考,当我使用 difftime 发布解决方案时,我将结果保留在“双”变量中,以处理 /60 截断。请在回复时保持礼貌。
        • 抱歉,如果我听起来不礼貌;我不是故意的。即使没有localtime(),您自己的方法也需要某种方法来获得struct tm,这需要许多除法运算,这些运算加起来比模数长得多(您可以使用其他运算,但据我所知他们不会比我的模数快)。
        【解决方案6】:

        C99版本:

        #include <math.h>
        #include <stdio.h>
        #include <time.h>
        
        int main(void)
        {
            struct tm now = *localtime(&(time_t){ time(NULL) });
            struct tm then = now;
            then.tm_hour = 21;
            then.tm_min = 0;
            then.tm_sec = 0;
            int dt = ((int)round(
                difftime(mktime(&then), mktime(&now)) / 60) + 24 * 60) % (24 * 60);
            printf("time till 9pm: %i minutes\n", dt);
        }
        

        【讨论】:

          【解决方案7】:

          更深奥但帮助不大的答案是没有简单的答案。

          你怎么知道今天晚上 9 点?好的,当然,我确信所有存在的时区都不会跳过 21:00,但它们每年都会在半夜跳过几个小时。

          日历是复杂性的灾难。小心。

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 2014-02-08
            • 2011-05-08
            • 1970-01-01
            • 1970-01-01
            • 2022-07-15
            • 1970-01-01
            • 2018-12-28
            相关资源
            最近更新 更多