一、设置系统日期时间的方法
1.命令行工具
date 命令:是Linux系统中用于查看和设置系统时间的常用命令行工具。通过date -s选项,可以手动设置系统时间。
sudo date -s "YYYY-MM-DD HH:MM:SS"
hwclock 命令:用于查询和设置硬件时钟(RTC,实时时钟)。虽然它主要用于硬件时钟,但也可以用来将硬件时钟的时间同步到系统时钟,或者将系统时钟的时间写入硬件时钟。
//查看硬件时钟
sudo hwclock --show
//设置硬件时钟(需要管理员权限)
sudo hwclock --set --date="YYYY-MM-DD HH:MM:SS"
timedatectl 命令( systemd 系统):在使用 systemd 的 Linux 发行版中,timedatectl 是一个用于查询和更改系统日期和时间的命令行工具。它提供了比date命令更丰富的功能和选项。
//设置系统时间
sudo timedatectl set-time "YYYY-MM-DD HH:MM:SS"
//设置时区
sudo timedatectl set-timezone "Asia/Shanghai"
2.NTP(网络时间协议)
NTP本身不是一个函数或命令,但它是一种用于同步计算机时间的协议。在Linux系统中,可以使用NTP客户端(如 ntpd、chronyd 等)来自动从网络上的时间服务器同步时间。
也可以通过编写C语言程序来配置NTP客户端,最好通过调用系统命令(如 ntpdate)或使用NTP客户端的库(如果可用)来实现类似的功能。
3.系统调用和库函数(间接方法)
在某些情况下,需要编写C语言程序来调用系统命令(如使用 system() 函数)或执行其他间接操作来设置系统时间。
4.settimeofday() 函数
在ARM Linux上使用C语言设置系统日期和时间,通常需要调用 settimeofday() 函数,该函数是 POSIX标准 的一部分,用于设置系统的当前时间。不过,由于 settimeofday() 需要超级用户权限,因此需要以root用户身份运行程序。
二、代码测试
2.1 系统调用
测试代码
#include <stdio.h>
#include <string.h>
#include <time.h>
int main(int argc,char*argv[])
{
FILE *fstream=NULL;
char buff[1024];
char cmd[1024];
time_t now;
memset(buff,0,sizeof(buff));
memset(cmd,0,sizeof(cmd));
sprintf(cmd,"sudo date -s \"%d-%d-%d %d:%d:%d\"",2024,8,7,9,50,0);
printf("%s\r\n",cmd);
if(NULL==(fstream=popen(cmd,"r"))) // cmd 指令
{
fprintf(stderr,"execute command failed: %s",strerror(perror));
return -1;
}
printf("%s\r\n","haha-start");
while(NULL!=fgets(buff, sizeof(buff), fstream)) // 获取 cmd 指令返回的数据信息
{
printf("%s",buff);
}
printf("%s\r\n","haha-end");
pclose(fstream); // 关闭
// 验证系统时间是否已更改(可选)
time(&now);
printf("系统时间已设置为: %s", ctime(&now));
return 0;
}
测试结果
2.2 settimeofday() 函数
测试代码如下:
#include <stdio.h>
#include <time.h>
#include <sys/time.h>
#include <stdlib.h>
int main()
{
struct timeval tv;
struct tm tm_new;
time_t now;
// 获取当前时间(以秒为单位)
time(&now);
// 将time_t转换为struct tm
// 注意:localtime()返回的是指向静态内存的指针,每次调用可能会覆盖之前的结果
struct tm *tm_now = localtime(&now);
if (tm_now == NULL)
{
perror("localtime");
return EXIT_FAILURE;
}
// 复制当前时间,以便修改
tm_new = *tm_now;
// 假设我们要将时间设置为2023年10月1日 12:00:00
tm_new.tm_year = 2023 - 1900; // 年份,从1900年开始计数
tm_new.tm_mon = 10 - 1; // 月份,从0开始计数
tm_new.tm_mday = 1; // 日
tm_new.tm_hour = 12; // 小时
tm_new.tm_min = 0; // 分钟
tm_new.tm_sec = 0; // 秒
// 将struct tm转换回time_t
// 注意:mktime()会修改传入的struct tm,将其标准化(比如月份从0调整为1-12)
now = mktime(&tm_new);
if (now == (time_t)-1)
{
perror("mktime");
return EXIT_FAILURE;
}
// 设置tv_sec
tv.tv_sec = now;
// 如果需要,也可以设置tv_usec(微秒)
tv.tv_usec = 0;
// 调用settimeofday()设置系统时间
// 注意:这需要root权限
if (settimeofday(&tv, NULL) == -1)
{
perror("settimeofday");
return EXIT_FAILURE;
}
// 验证系统时间是否已更改(可选)
printf("系统时间已设置为: %s", ctime(&now));
return EXIT_SUCCESS;
}
切换到 root 用户,指令
su
编译程序,并执行,测试结果如下
gcc test.c -o test
退出 root 用户,指令
exit
或者
先编译,指令为
sudo gcc test.c -o test
再切换到 root 用户执行即可
su