ctime 学习笔记

ctime 学习笔记

引入头文件 time.hctime

函数

asctime

char* asctime (const struct tm * timeptr);

Convert tm structure to string

The string is followed by a new-line character ('\n') and terminated with a null-character.

It is defined with a behavior equivalent to:

char* asctime(const struct tm *timeptr)
{
  static const char wday_name[][4] = {
    "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"
  };
  static const char mon_name[][4] = {
    "Jan", "Feb", "Mar", "Apr", "May", "Jun",
    "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"
  };
  static char result[26];
  sprintf(result, "%.3s %.3s%3d %.2d:%.2d:%.2d %d\n",
    wday_name[timeptr->tm_wday],
    mon_name[timeptr->tm_mon],
    timeptr->tm_mday, timeptr->tm_hour,
    timeptr->tm_min, timeptr->tm_sec,
    1900 + timeptr->tm_year);
  return result;
}

废话不多 copy ,直接看代码即可。显然:

  • 格式是固定的 Www Mmm dd hh:mm:ss yyyyWed Feb 13 15:46:11 2013
  • 输出字符串末尾有 \n

ctime

char* ctime (const time_t * timer);

貌似和 asctime 没区别……

clock

clock_t clock (void);

Clock program

Returns the processor time consumed by the program.

The value returned is expressed in clock ticks, which are units of time of a constant but system-specific length (with a relation of CLOCKS_PER_SEC clock ticks per second).

The epoch used as reference by clock varies between systems, but it is related to the program execution (generally its launch). To calculate the actual processing time of a program, the value returned by clock shall be compared to a value returned by a previous call to the same function.

常用的程序计时工具。这里只给简介,别的不多 copy ,细节直接翻官方文档即可。

返回 CPU 时间,参考 clock_t

difftime

double difftime (time_t end, time_t beginning);

Return difference between two times

Calculates the difference in seconds between beginning and end.

Example

/* difftime example */
#include <stdio.h>      /* printf */
#include <time.h>       /* time_t, struct tm, difftime, time, mktime */

int main ()
{
  time_t now;
  struct tm newyear;
  double seconds;

  time(&now);  /* get current time; same as: now = time(NULL)  */

  newyear = *localtime(&now);

  newyear.tm_hour = 0; newyear.tm_min = 0; newyear.tm_sec = 0;
  newyear.tm_mon = 0;  newyear.tm_mday = 1;

  seconds = difftime(now, mktime(&newyear));

  printf ("%.f seconds since new year in the current timezone.\n", seconds);

  return 0;
}

Output:

3777291 seconds since new year in the current timezone. 

计算时间差,这个可太有用了!!

  • 参数顺序反人类
  • 返回值的类型是 double

gmtime

struct tm * gmtime (const time_t * timer);

Convert time_t to tm as UTC time

Uses the value pointed by timer to fill a tm structure with the values that represent the corresponding time, expressed as a UTC time (i.e., the time at the GMT timezone).

localtime

struct tm * localtime (const time_t * timer);

Convert time_t to tm as local time

Uses the value pointed by timer to fill a tm structure with the values that represent the corresponding time, expressed for the local timezone.

mktime

time_t mktime (struct tm * timeptr);

Convert tm structure to time_t

Returns the value of type time_t that represents the local time described by the tm structure pointed by timeptr (which may be modified).

This function performs the reverse translation that localtime does.

The values of the members tm_wday and tm_yday of timeptr are ignored, and the values of the other members are interpreted even if out of their valid ranges (see struct tm). For example, tm_mday may contain values above 31, which are interpreted accordingly as the days that follow the last day of the selected month.

A call to this function automatically adjusts the values of the members of timeptr if they are off-range or -in the case of tm_wday and tm_yday- if they have values that do not match the date described by the other members.

Example:

/* mktime example: weekday calculator */
#include <stdio.h>      /* printf, scanf */
#include <time.h>       /* time_t, struct tm, time, mktime */

int main ()
{
  time_t rawtime;
  struct tm * timeinfo;
  int year, month ,day;
  const char * weekday[] = { "Sunday", "Monday",
                             "Tuesday", "Wednesday",
                             "Thursday", "Friday", "Saturday"};

  /* prompt user for date */
  printf ("Enter year: "); fflush(stdout); scanf ("%d",&year);
  printf ("Enter month: "); fflush(stdout); scanf ("%d",&month);
  printf ("Enter day: "); fflush(stdout); scanf ("%d",&day);

  /* get current timeinfo and modify it to the user's choice */
  time ( &rawtime );
  timeinfo = localtime ( &rawtime );
  timeinfo->tm_year = year - 1900;
  timeinfo->tm_mon = month - 1;
  timeinfo->tm_mday = day;

  /* call mktime: timeinfo->tm_wday will be set */
  mktime ( timeinfo );

  printf ("That day is a %s.\n", weekday[timeinfo->tm_wday]);

  return 0;
}

Output:

 Enter year: 2000 
 Enter month: 5 
 Enter day: 20 
 That day is a Saturday. 
  • localtime 的逆操作
  • 函数内部忽略 tm_wday 和 tm_yday 参数
  • 输入参数超出预设范围按预设范围的最大值算
  • 既补充作为参数的日期结构体,又返回秒数,一箭双雕

strftime

size_t strftime (char* ptr, size_t maxsize, const char* format, const struct tm* timeptr );

Format time as string

Copies into ptr the content of format, expanding its format specifiers into the corresponding values that represent the time described in timeptr, with a limit of maxsize characters.

Example

/* strftime example */
#include <stdio.h>      /* puts */
#include <time.h>       /* time_t, struct tm, time, localtime, strftime */

int main ()
{
  time_t rawtime;
  struct tm * timeinfo;
  char buffer [80];

  time (&rawtime);
  timeinfo = localtime (&rawtime);

  strftime (buffer,80,"Now it's %I:%M%p.",timeinfo);
  puts (buffer);

  return 0;
}

Example output:

 Now it's 03:21PM. 

超级无敌豪华加长尊享版的 asctimectime 函数。不过使用方式也繁琐了。

有关格式化的各种设置太多了,这里不 copy ,直接参考官方文档即可。

time

time_t time (time_t* timer);

Get current time

Get the current calendar time as a value of type time_t.

The function returns this value, and if the argument is not a null pointer, it also sets this value to the object pointed by timer.

The value returned generally represents the number of seconds since 00:00 hours, Jan 1, 1970 UTC (i.e., the current unix timestamp). Although libraries may use a different representation of time: Portable programs should not use the value returned by this function directly, but always rely on calls to other elements of the standard library to translate them to portable types (such as localtime, gmtime or difftime).

Example

/* time example */
#include <stdio.h>      /* printf */
#include <time.h>       /* time_t, struct tm, difftime, time, mktime */

int main ()
{
  time_t timer;
  struct tm y2k = {0};
  double seconds;

  y2k.tm_hour = 0;   y2k.tm_min = 0; y2k.tm_sec = 0;
  y2k.tm_year = 100; y2k.tm_mon = 0; y2k.tm_mday = 1;

  time(&timer);  /* get current time; same as: timer = time(NULL)  */

  seconds = difftime(timer,mktime(&y2k));

  printf ("%.f seconds since January 1, 2000 in the current timezone", seconds);

  return 0;
}

Possible output:

414086872 seconds since January 1, 2000 in the current timezone 

关键数据结构

clock_t

Clock type

Alias of a fundamental arithmetic type capable of representing clock tick counts.

Clock ticks are units of time of a constant but system-specific length, as those returned by function clock.

This is the type returned by clock.

一点自己的补充理解:

  • 系统滴答时钟,调用 clock 函数返回,可以除以 宏 CLOCKS_PER_SEC 换算成秒。精确计算程序执行时间用。
  • 只是用在当前程序上的 CPU 时间,不是现实世界时间。(在 clock 函数的介绍里有补充说明)
  • 根据系统规定数据长度。不过我在网上随手查了个定义,是 long ,如果间隔太长估计会溢出。
  • 应该没有固定的开始和结束时间点。

size_t

Unsigned integral type

Alias of one of the fundamental unsigned integer types.

It is a type able to represent the size of any object in bytes: size_t is the type returned by the sizeof operator and is widely used in the standard library to represent sizes and counts.

In <ctime>, it is used in the function strftime as the type of its parameter maxsize and as its return value. In both cases it is used to express counts of characters.

随处可见的整数类型。

time_t

Time type

Alias of a fundamental arithmetic type capable of representing times, as those returned by function time.

For historical reasons, it is generally implemented as an integral value representing the number of seconds elapsed since 00:00 hours, Jan 1, 1970 UTC (i.e., a unix timestamp). Although libraries may implement this type using alternative time representations.

Portable programs should not use values of this type directly, but always rely on calls to elements of the standard library to translate them to portable types.

显然,这是现实世界时间。

struct tm

Time structure
Structure containing a calendar date and time broken down into its components.

The structure contains nine members of type int (in any order), which are:

  • C99 (C++11)
Member Type Meaning Range
tm_sec int seconds after the minute 0-60*
tm_min int minutes after the hour 0-59
tm_hour int hours since midnight 0-23
tm_mday int day of the month 1-31
tm_mon int months since January 0-11
tm_year int years since 1900 ``
tm_wday int days since Sunday 0-6
tm_yday int days since January 1 0-365
tm_isdst int Daylight Saving Time flag ``

The Daylight Saving Time flag (tm_isdst) is greater than zero if Daylight Saving Time is in effect, zero if Daylight Saving Time is not in effect, and less than zero if the information is not available.

* tm_sec is generally 0-59. The extra range is to accommodate for leap seconds in certain systems.

  • 部分参数含义设计反人类,所以注意各参数意义,不要想当然!
  • 背诵并默写上述表格!

一些小练习

LeetCode

  • 1360. Number of Days Between Two Dates

    // Example 1:
    // Input: date1 = "2019-06-29", date2 = "2019-06-30"
    // Output: 1
    class Solution {
    public:
        int daysBetweenDates(string date1, string date2) {
            int y1, m1, d1, y2, m2, d2;
            sscanf(date1.c_str(), "%d-%d-%d", &y1, &m1, &d1);
            sscanf(date2.c_str(), "%d-%d-%d", &y2, &m2, &d2);
            struct tm date1_t = {
                .tm_year = y1 - 1900,
                .tm_mon = m1 - 1,
                .tm_mday = d1
            };
            struct tm date2_t = {
                .tm_year = y2 - 1900,
                .tm_mon = m2 - 1,
                .tm_mday = d2
            };
            return (int)fabs(difftime(mktime(&date1_t), mktime(&date2_t)) / (24*3600));
        }
    };
    
  • 1185. Day of the Week

    // Example 1:
    // Input: day = 31, month = 8, year = 2019
    // Output: "Saturday"
    class Solution {
    public:
        const string WEEKDAYS[7] = {"Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"};
        string dayOfTheWeek(int day, int month, int year) {
            struct tm date = {
                .tm_year = year - 1900,
                .tm_mon = month - 1,
                .tm_mday = day
            };
            mktime(&date);
            return WEEKDAYS[date.tm_wday];
        }
    };
    
  • 1154. Day of the Year

    // Example 1:
    // Input: date = "2019-01-09"
    // Output: 9
    // Explanation: Given date is the 9th day of the year in 2019.
    class Solution {
    public:
        int dayOfYear(string date) {
            int year, month, day;
            sscanf(date.c_str(), "%d-%d-%d", &year, &month, &day);
            struct tm date_t = {
                .tm_year = year - 1900,
                .tm_mon = month - 1,
                .tm_mday = day
            };
            mktime(&date_t);
            return date_t.tm_yday + 1;
        }
    };
    

网上随手搜的一些练习题

得到下一秒的时间

例如输入当前时间2006年12月20日19时17分59秒,
计算后输出时间是2006年12月20日19时18分00秒。
程序要求:
1) 程序应该可以运行:通过控制台输入数据,输出数据通过printf给出;
2) 程序结构明了、逻辑清晰;
3) 请考虑闰年、月份(大小)等逻辑;
4) 程序功能完整;

// 输入输出偷懒一下嘿嘿
int main() {
    int year, month, day, hour, minute, second;
    cin >> year >> month >> day >> hour >> minute >> second;
    struct tm date_t = {
        .tm_year = year - 1900,
        .tm_mon = month - 1,
        .tm_mday = day,
        .tm_hour = hour,
        .tm_min = minute,
        .tm_sec = second
    };
    time_t seconds = mktime(&date_t);
    seconds++;
    cout << asctime(localtime(&seconds)) << endl;
    return 0;
}
// 2006 12 20 19 17 59
// Wed Dec 20 19:18:00 2006

// 2019 12 31 23 59 59
// Wed Jan  1 00:00:00 2020

// 2020 02 28 23 59 59
// Sat Feb 29 00:00:00 2020

Date after n days

There have been given a date as an input in day, month, year, output the date after n days.

// 输入输出偷懒一下嘿嘿
int main() {
    int year, month, day, n;
    cin >> year >> month >> day >> n;
    struct tm date_t = {
        .tm_year = year - 1900,
        .tm_mon = month - 1,
        .tm_mday = day
    };
    time_t seconds = mktime(&date_t);
    seconds += n * 24 * 3600;
    cout << asctime(localtime(&seconds)) << endl;
    return 0;
}
// 2020 02 01 28
// Sat Feb 29 00:00:00 2020

// 2020 02 01 29
// Sun Mar  1 00:00:00 2020

// 2020 02 01 365
// Sun Jan 31 00:00:00 2021

判断年份是否为闰年

ctime 无关,只是补充在这里复习下公式。

闰年满足下面两个条件之一:

  1. 能被 4 整除,但不能被 100 整除
  2. 能被 400 整除

(year % 4 == 0 && year % 100 != 0) || (year % 400 == 0)

posted @ 2020-11-23 23:44  AdjWang  阅读(158)  评论(0)    收藏  举报