You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何用C语言编写统计运行天数的程序/函数(含Arduino场景)

统计程序运行天数的C语言实现(含Arduino项目适配)

一、通用C语言方案(桌面/服务器程序)

利用标准库<time.h>的时间戳功能,通过记录首次运行的时间戳,每次调用时计算与当前时间的差值,转换为天数。核心是用静态变量保存首次运行时间,确保函数内部状态持久化。

代码实现

#include <time.h>
#include <stdio.h>

int get_running_days() {
    static time_t start_time = 0; // 静态变量,仅初始化一次
    time_t current_time;
    
    // 首次调用时记录初始时间
    if (start_time == 0) {
        if (time(&start_time) == -1) {
            perror("Failed to get system time");
            return -1; // 时间获取失败返回错误码
        }
        return 0; // 首次执行返回0天
    }
    
    // 获取当前时间并计算差值
    if (time(&current_time) == -1) {
        perror("Failed to get system time");
        return -1;
    }
    
    // 计算秒数差,转换为天数(一天=86400秒)
    double elapsed_days = difftime(current_time, start_time) / 86400.0;
    return (int)elapsed_days; // 取整数部分,按完整24小时周期统计
}

// 测试示例
int main() {
    printf("First call: %d days\n", get_running_days());
    // 模拟延迟(实际运行中无需此代码)
    // sleep(86400 * 3);
    printf("After 3 days: %d days\n", get_running_days());
    return 0;
}

注意事项

  • 依赖系统时钟的准确性,若系统时间被修改,统计结果会受影响。
  • difftime()处理时间戳差值,避免溢出问题(time_t通常为64位,无需担心长期运行溢出)。

二、Arduino项目专用方案

Arduino场景分两种情况:单次运行不保留断电状态、断电后需继续统计(依赖RTC模块)。

1. 无RTC模块(单次运行)

利用Arduino内置的millis()函数获取开机后的毫秒数,通过静态变量记录首次调用时间,计算天数差。需注意millis()的溢出(unsigned long类型约49天溢出,但unsigned减法会自动处理溢出)。

代码实现

unsigned long get_running_days() {
    static unsigned long start_millis = 0;
    unsigned long current_millis = millis();
    
    // 首次调用初始化
    if (start_millis == 0) {
        start_millis = current_millis;
        return 0;
    }
    
    // 计算毫秒差,转换为天数
    unsigned long elapsed_ms = current_millis - start_millis;
    return elapsed_ms / (1000UL * 60 * 60 * 24); // UL确保无溢出
}

// 使用示例(在loop中调用)
void setup() {
    Serial.begin(9600);
}

void loop() {
    unsigned long days = get_running_days();
    Serial.print("Running days: ");
    Serial.println(days);
    
    // 基于天数的条件判断示例
    if (days >= 60 && days <= 90) {
        digitalWrite(LED_BUILTIN, HIGH);
    } else {
        digitalWrite(LED_BUILTIN, LOW);
    }
    
    delay(1000);
}

2. 带RTC模块(断电持久化)

若设备需要断电后继续统计天数,需搭配RTC模块(如DS3231),通过Unix时间戳记录首次运行时间,重启后从RTC读取当前时间计算差值。

代码实现(以DS3231为例)

#include <Wire.h>
#include <DS3231.h>

DS3231 rtc;
static time_t start_timestamp = 0; // 保存首次运行的Unix时间戳

unsigned int get_running_days() {
    // 首次调用或重启后初始化
    if (start_timestamp == 0) {
        start_timestamp = rtc.getUnixTime();
        return 0;
    }
    
    time_t current_timestamp = rtc.getUnixTime();
    double elapsed_days = difftime(current_timestamp, start_timestamp) / 86400.0;
    return (unsigned int)elapsed_days;
}

void setup() {
    Serial.begin(9600);
    Wire.begin();
    rtc.begin();
    
    // 可选:若RTC未设置时间,可初始化(仅执行一次)
    // rtc.setDateTime(2024, 5, 20, 9, 50, 0); // 年,月,日,时,分,秒
}

void loop() {
    unsigned int days = get_running_days();
    Serial.print("Running days: ");
    Serial.println(days);
    
    // 60-90天的条件逻辑
    if (days >= 60 && days <= 90) {
        // 执行设备控制逻辑
    }
    
    delay(3600000); // 每小时刷新一次
}

关键说明

  • 示例中按完整24小时周期统计天数(如周五9:50到周一9:50刚好3天),符合需求。
  • 若需按自然日(跨零点就算一天),需额外解析RTC的年月日,实现日期差计算逻辑。

内容的提问来源于stack exchange,提问作者hollowaytyl

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.22 21:42:13