c语言中日期和时间_C中的日期和时间

c语言中日期和时间

Every time I need to work with dates and times in C I find myself scrabbling around trying to refresh my memory on how the data structures and functions provided by time.h work. I have therefore put together a short program to demo the most important functionality, mainly as a reference for myself but I hope you find it useful as well.

每当我需要在CI中使用日期和时间时,都会发现自己在尝试刷新有关time.h提供的数据结构和功能如何工作的记忆。 因此,我整理了一个简短的程序来演示最重要的功能,主要是作为给自己的参考,但我希望您也觉得它有用。

Dealing with dates and times is a pain. The units are incredibly messy — not only do we have to deal with the various units being split up in different ways, we have to deal with leap years, daylight saving time, time zones and even the occasional leap second.

处理日期和时间很痛苦。 这些单位非常混乱-我们不仅必须处理以不同方式拆分的各个单位,而且还必须处理we年,夏时制,时区,甚至偶有leap秒。

Fortunately every mainstream language or framework provides us with off-the-shelf functionality for handling dates and times but even these are not entirely straightforward. This is particularly true with C so I thought I would provide myself with a few bits of sample code which I can copy and paste whenever I need, and also share with anybody else who might find it useful.

幸运的是,每种主流语言或框架都为我们提供了用于处理日期和时间的现成功能,但是即使这些也不是完全简单的。 对于C来说尤其如此,因此我想为自己提供一些示例代码,可以在需要时复制和粘贴这些示例代码,并且还可以与其他可能有用的人共享。

时间 (time.h)

The C standard library includes time.h which provides us with a struct and an integer type to represent dates and times. These are combined; there are no separate types for dates and times. This makes sense when you think about it, as the separation between the two is entirely arbitrary and has no real meaning.

C标准库包括time.h ,它为我们提供了一个结构和一个整数类型来表示日期和时间。 这些是结合在一起的。 日期和时间没有单独的类型。 考虑到这一点,这是有道理的,因为两者之间的分隔完全是任意的,没有实际意义。

These are the two types used to represent dates and times.

这是用于表示日期和时间的两种类型。

Image for post

Of course the two types show above both represent what is essentially the same information, albeit in very different forms. The standard library therefore provides us with functions for obtaining a variable of each type from the other.

当然,以上显示的两种类型都表示本质上相同的信息,尽管形式非常不同。 因此,标准库为我们提供了从彼此获取每种类型的变量的函数。

Image for post

Finally let’s look at a few functions to provide human-readable strings from time_t variables or tm structs.

最后,让我们看一些从time_t变量或tm结构提供人类可读字符串的函数。

Image for post

该项目 (The Project)

For this project I will write three functions to illustrate the types and functions listed above.

对于这个项目,我将编写三个函数来说明上面列出的类型和函数。

  • Get the current time as a time_t, use it to create tm structs in both GMT and local time, then print out the members of the local time struct

    time_t获取当前时间,使用它在GMT和本地时间中创建tm结构,然后打印出本地时间结构的成员

  • Create and initialize a tm struct, then use mktime to both normalize the tm and get a time_t

    创建并初始化tm结构,然后使用mktime标准化tm并获取time_t

  • Get the local time and print it in various formats using strftime

    获取本地时间并使用strftime以各种格式打印

The project consists of just one file called datetime.c which you can clone/download the Github repository.

该项目仅包含一个名为datetime.c的文件,您可以克隆/下载Github存储库

This is the first part.

这是第一部分。

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


void current_time(void);
void create_time(void);
void time_to_string(void);




int main(int argc, char* argv[])
{
    puts("-------------------");
    puts("| codedrome.com   |");
    puts("| Dates and Times |");
    puts("-------------------\n");


    current_time();


    // create_time();


    // time_to_string();


    return EXIT_SUCCESS;
}




void current_time(void)
{
    // Get current time as time_t which
    // is an integer, usually long.
    // This is generally the number of
    // seconds from midnight on 1 Jan 1970.
    time_t t = time(NULL);


    // Get tm structs from time_t.
    // tm has members for seconds, minutes,
    // hours, day, month, year etc.
    struct tm* tm_gmt = gmtime(&t);
    struct tm* tm_local = localtime(&t);


    printf("Current GMT time is:\n%s\n", asctime(tm_gmt));


    printf("Current local time is:\n%s\n", asctime(tm_local));


    // Print the members of the local tm struct.
    // Note these are all of type int.
    puts("The members of the local tm struct are:");
    printf("tm_sec   %d\n", tm_local->tm_sec);
    printf("tm_min   %d\n", tm_local->tm_min);
    printf("tm_hour  %d\n", tm_local->tm_hour);
    printf("tm_mday  %d\n", tm_local->tm_mday);
    printf("tm_mon   %d\t0-based\n", tm_local->tm_mon);
    printf("tm_year  %d\tfrom 1900\n", tm_local->tm_year);
    printf("tm_wday  %d\t0-based from Sunday\n", tm_local->tm_wday);
    printf("tm_yday  %d\t0-based\n", tm_local->tm_yday);
    printf("tm_isdst %d\t-1 = not known, 0 = no, 1 = yes\n", tm_local->tm_isdst);
}

The main function merely calls the other three functions.

main函数仅调用其他三个函数。

I don’t usually include a lot of comments unless something unusual is going on which needs an explanation, but as this code is intended mainly as a reference I have included comprehensive descriptions. Therefore I won’t include details of the code in the text.

除非正在进行一些不寻常的事情,需要解释,否则我通常不会包含很多评论,但是由于此代码主要是作为参考,因此我已经进行了全面的描述。 因此,我不会在文本中包含代码的详细信息。

When you have read the code and comments compile the program and run it:

阅读代码和注释后,编译程序并运行它:

gcc datetime.c -std=c11 -lm -o datetime ./datetime

gcc datetime.c -std=c11 -lm -o datetime ./datetime

Image for post

Note that tm_mon, tm_wday and tm_yday are zero-based, and that the year counts up or down from 1900.

请注意, tm_montm_wdaytm_yday从零开始,并且年份从1900开始递增或递减。

Now let’s look at create_time.

现在让我们看一下create_time

void create_time(void)
{
    // Create and initialize a tm struct.
    struct tm st = {.tm_sec = 30,
                    .tm_min = 15,
                    .tm_hour = 9,
                    .tm_mday = 12,
                    .tm_mon = 7 - 1, // 0-based so 6 is July
                    .tm_year = 2019 - 1900, // 1900 + or -
                    .tm_isdst = 1};


    // Create a time_t from a tm struct.
    // This also sets tm_wday and tm_yday.
    time_t t = mktime(&st);


    printf("The value of the time_t variable is:\n%ld\n\n", t);


    printf("which represents:\n%s\n", ctime(&t));


    puts("The mkdir function set these members of the tm struct:");
    printf("tm_wday  %d\t0-based from Sunday\n", st.tm_wday);
    printf("tm_yday  %d\t0-based\n", st.tm_yday);
}

When creating a tm I have used 7 as the month but subtracted 1, and 2019 as the year but subtracted 1900. This emphasises that they start at 0 and 1900 respectively.

创建tm我将7用作月份,但减去1,将2019用作年份,但减去1900。这强调了它们分别从0和1900开始。

After printing out the value of the time_t variable both as a number and a human-readable string I have printed tm_wday and tm_yday to illustrate that the mktime function sets these.

在将time_t变量的值打印为数字和人类可读的字符串之后,我打印了tm_wdaytm_yday来说明mktime函数设置了这些值。

The mktime function also adjusts any values which exceed their maximum. For example if you create a tm struct with a date of 31 June then mktime will change it to 1 July. For this reason it is important to set all six date/time members even if you aren’t interested in them. If you do not they will contain garbage values which mktime will use to adjust the members which you did set. (You don’t have to look far to find complaints about this “bug”!)

mktime函数还可以调整任何超出其最大值的值。 例如,如果您创建日期为6月31日的tm结构,则mktime会将其更改为7月1日。 因此,即使您对六个日期/时间成员都不感兴趣,也很重要。 如果不这样做,它们将包含垃圾值, mktime将使用这些值来调整您设置的成员。 (您不必费劲就可以找到有关此“错误”的投诉!)

In main comment out current_time();, uncomment create_time(); and build and run again. This is the output.

在主要评论中, current_time(); ,取消注释create_time(); 然后重新构建并运行。 这是输出。

Image for post

The fixed string format provided by asctime and ctime is OK for demonstration or perhaps writing to a log but isn’t very flexible. The strftime function allows us to specify a format string so we can create a string with the various members of a tm struct in any order or format we want.

asctimectime提供的固定字符串格式可以演示或写入日志,但不是很灵活。 strftime函数允许我们指定格式字符串,这样我们就可以使用所需的任何顺序或格式,使用tm结构的各个成员创建字符串。

strftime takes the following arguments:

strftime采用以下参数:

  • char* restrict n — a buffer to hold the formatted date

    char* restrict n —一个缓冲区,用于保存格式化的日期

  • size_t n — the maximum number of characters to write

    size_t n —要写入的最大字符数

  • const char* restrict format — a string representing the format

    const char* restrict format -表示格式的字符串

  • const struct tm* restrict timeptr — the tm to create a string representation of

    const struct tm* restrict timeptr —用于创建以下内容的字符串表示形式的tm

The format string can contain any number of specifiers consisting of the % sign followed by an upper case or lower case letter. I won’t list all the valid letters but you might like to read this http://man7.org/linux/man-pages/man3/strftime.3.html.

格式字符串可以包含任意数量的说明符,由%符号,大写或小写字母组成。 我不会列出所有有效字母,但是您可能想阅读http://man7.org/linux/man-pages/man3/strftime.3.html

Now take a look at the code which uses strftime on the current time with three different formats.

现在来看一下在当前时间使用strftime的三种不同格式的代码。

void time_to_string(void)
{
    char datestring[64];


    time_t t = time(NULL);
    struct tm* tm_local = localtime(&t);


    // YYYY-MM-DD
    strftime(datestring, 64, "%Y-%m-%d", tm_local); // can use the %F shorthand
    puts(datestring);


    // Day, day of month, month, year in full
    strftime(datestring, 64, "%A %d %B %Y", tm_local);
    puts(datestring);


    // HH:MM:SS
    strftime(datestring, 64, "%H:%M:%S", tm_local); // can use the %T shorthand
    puts(datestring);
}

After getting a tm with the local time I have used strftime with three different format string examples. A few of the more common formats have single letter shortcuts, two of which I have mentioned in the comments.

在获取本地时间的tm之后,我将strftime与三个不同格式的字符串示例一起使用。 一些较常见的格式具有单字母快捷键,我在注释中提到了其中的两个。

In main comment out create_time();, uncomment time_to_string(); and build and run again. This is the output.

main注释中, create_time(); ,取消注释time_to_string(); 然后重新构建并运行。 这是输出。

Image for post

As you can see strftime provides as much flexibility as you need. Not only do the various % + letter specifiers let you format the members of a tm in any way you need but you can also include other characters or text in the output.

如您所见, strftime提供了所需的灵活性。 各种% +字母说明符不仅可以让您以所需的任何方式格式化tm的成员,而且还可以在输出中包括其他字符或文本。

翻译自: https://medium.com/programming-in-c/dates-and-times-in-c-9fc7be4e3625

c语言中日期和时间

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值