TLPI-Chapter 10 时间

日历时间Calendat Time

UNIX系统内部对时间的表示均是以自1970年1月1日的零点以来的秒数来度量。日历时间存储与类型time_t的变量中,此类型是由SUSv3定义的整数类型。
系统调用gettimeofday(),可于tv指向的缓冲区中返回日历时间。

#include <sys/time.h>
int gettimeofday(struct timeval *tv, struct timezone *tz);
          Returns 0 on success, or –1 on error
参数tv是指向如下数据结构的一个指针:
struct timeval {
    __kernel_time_t        tv_sec;        /* seconds */
    __kernel_suseconds_t    tv_usec;    /* microseconds */
};

在现代X86-32系统上,gettimeofday()可以提供微妙级的准确度。
time函数基于gettimeofday实现,time精度秒级,gettimeofday可以达到微妙。

#include <time.h>
time_t time(time_t *timep);
        Returns number of seconds since the Epoch,or (time_t) –1 on error
时间转换函数


将time_t转换为可打印格式

#include <time.h>
char *ctime(const time_t *timep)

ctime返回的字符串经由静态分配,下一次对ctime()的调用会将其覆盖。
函数gmtime()和localtime()可将time_t类型转换为一个所谓的分解时间。分解时间置于一个经由静态分配的结构中,其地址则作为函数结果返回。
函数gmtime()能够把日历时间转换为一个对应于UTC的分解时间。
函数localtime()需要考虑时区和夏令时设置,返回对应于系统本地时间的一个分解时间。

#include<time.h>
struct tm *localtime(const time_t * timep);
struct tm *gmtime(const time_t *timep);

函数mktime()将一个本地时区的分解时间转换为time_t,并将结果返回。
函数asctime()则从分解时间转换为打印时间。
char *asctime(const struct tm *timeptr);
在参数tm中提取一个指向分解时间结构的指针,asctime()则会返回一指针,指向经由静态分配的字符串,内含时间,格式则与ctime()相同。

/*************************************************************************\
*                  Copyright (C) Michael Kerrisk, 2015.                   *
*                                                                         *
* This program is free software. You may use, modify, and redistribute it *
* under the terms of the GNU General Public License as published by the   *
* Free Software Foundation, either version 3 or (at your option) any      *
* later version. This program is distributed without any warranty.  See   *
* the file COPYING.gpl-v3 for details.                                    *
\*************************************************************************/

/* Listing 10-1 */

/* calendar_time.c

   Demonstrate the use of functions for working with calendar time.

   This program retrieves the current time and displays it in various forms.
*/
#include <locale.h>
#include <time.h>
#include <sys/time.h>
#include "tlpi_hdr.h"

#define SECONDS_IN_TROPICAL_YEAR (365.24219 * 24 * 60 * 60)

int
main(int argc, char *argv[])
{
    time_t t;
    struct tm *gmp, *locp;
    struct tm gm, loc;
    struct timeval tv;

    /* Retrieve time, convert and display it in various forms */

    t = time(NULL);
    printf("Seconds since the Epoch (1 Jan 1970): %ld", (long) t);
    printf(" (about %6.3f years)\n", t / SECONDS_IN_TROPICAL_YEAR);

    if (gettimeofday(&tv, NULL) == -1)
        errExit("gettimeofday");
    printf("  gettimeofday() returned %ld secs, %ld microsecs\n",
            (long) tv.tv_sec, (long) tv.tv_usec);

    gmp = gmtime(&t);
    if (gmp == NULL)
        errExit("gmtime");

    gm = *gmp;          /* Save local copy, since *gmp may be modified
                           by asctime() or gmtime() */
    printf("Broken down by gmtime():\n");
    printf("  year=%d mon=%d mday=%d hour=%d min=%d sec=%d ", gm.tm_year,
            gm.tm_mon, gm.tm_mday, gm.tm_hour, gm.tm_min, gm.tm_sec);
    printf("wday=%d yday=%d isdst=%d\n", gm.tm_wday, gm.tm_yday, gm.tm_isdst);

    /* The TZ environment variable will affect localtime().
       Try, for example:

                TZ=Pacific/Auckland calendar_time
    */

    locp = localtime(&t);
    if (locp == NULL)
        errExit("localtime");

    loc = *locp;        /* Save local copy */

    printf("Broken down by localtime():\n");
    printf("  year=%d mon=%d mday=%d hour=%d min=%d sec=%d ",
            loc.tm_year, loc.tm_mon, loc.tm_mday,
            loc.tm_hour, loc.tm_min, loc.tm_sec);
    printf("wday=%d yday=%d isdst=%d\n\n",
            loc.tm_wday, loc.tm_yday, loc.tm_isdst);

    printf("asctime() formats the gmtime() value as: %s", asctime(&gm));
    printf("ctime() formats the time() value as:     %s", ctime(&t));

    printf("mktime() of gmtime() value:    %ld secs\n", (long) mktime(&gm));
    printf("mktime() of localtime() value: %ld secs\n", (long) mktime(&loc));

    exit(EXIT_SUCCESS);
}

程序输出结果:

root@ubuntu:~/tlpi-dist/time# ./calendar_time 
Seconds since the Epoch (1 Jan 1970): 1508659096 (about 47.808 years)
  gettimeofday() returned 1508659096 secs, 249229 microsecs
Broken down by gmtime():
  year=117 mon=9 mday=22 hour=7 min=58 sec=16 wday=0 yday=294 isdst=0
Broken down by localtime():
  year=117 mon=9 mday=22 hour=15 min=58 sec=16 wday=0 yday=294 isdst=0

asctime() formats the gmtime() value as: Sun Oct 22 07:58:16 2017
ctime() formats the time() value as:     Sun Oct 22 15:58:16 2017
mktime() of gmtime() value:    1508630296 secs
mktime() of localtime() value: 1508659096 secs
root@ubuntu:~/tlpi-dist/time# 

程序说明:
函数localtime()需要考虑时区和夏令时设置,因此打印的是本地时间。比gmtime()返回的时间晚整8个小时。
函数gettimeofday确实可以精确到microsecs级别。
1508659096-1508630296=8*3600
函数strftime():
当把一个分解时间转换成打印格式时,函数strftime()可以提供更为精确的控制。
函数currTime()返回当前时间。

/*************************************************************************\
*                  Copyright (C) Michael Kerrisk, 2015.                   *
*                                                                         *
* This program is free software. You may use, modify, and redistribute it *
* under the terms of the GNU Lesser General Public License as published   *
* by the Free Software Foundation, either version 3 or (at your option)   *
* any later version. This program is distributed without any warranty.    *
* See the files COPYING.lgpl-v3 and COPYING.gpl-v3 for details.           *
\*************************************************************************/

/* Listing 10-2 */

/* curr_time.c

   Implement our currTime() function.
*/
#include <time.h>
#include "curr_time.h"          /* Declares function defined here */

#define BUF_SIZE 1000

/* Return a string containing the current time formatted according to
   the specification in 'format' (see strftime(3) for specifiers).
   If 'format' is NULL, we use "%c" as a specifier (which gives the'
   date and time as for ctime(3), but without the trailing newline).
   Returns NULL on error. */

char *
currTime(const char *format)
{
    static char buf[BUF_SIZE];  /* Nonreentrant */
    time_t t;
    size_t s;
    struct tm *tm;

    t = time(NULL);
    tm = localtime(&t);
    if (tm == NULL)
        return NULL;

    s = strftime(buf, BUF_SIZE, (format != NULL) ? format : "%c", tm);

    return (s == 0) ? NULL : buf;
}

函数strptime()是strftime()的逆向函数,将包含日期和时间的字符串转换成分解时间。
示例代码:

/*************************************************************************\
*                  Copyright (C) Michael Kerrisk, 2015.                   *
*                                                                         *
* This program is free software. You may use, modify, and redistribute it *
* under the terms of the GNU General Public License as published by the   *
* Free Software Foundation, either version 3 or (at your option) any      *
* later version. This program is distributed without any warranty.  See   *
* the file COPYING.gpl-v3 for details.                                    *
\*************************************************************************/

/* Listing 10-3 */

/* strtime.c

   Demonstrate the use of strptime() and strftime().

   Calls strptime() using the given "format" to process the "input-date+time".
   The conversion is then reversed by calling strftime() with the given
   "out-format" (or a default format if this argument is omitted).
*/
#if ! defined(__sun)
#ifndef _XOPEN_SOURCE
#define _XOPEN_SOURCE
#endif
#endif
#include <time.h>
#include <locale.h>
#include "tlpi_hdr.h"

#define SBUF_SIZE 1000

int
main(int argc, char *argv[])
{
    struct tm tm;
    char sbuf[SBUF_SIZE];
    char *ofmt;

    if (argc < 3 || strcmp(argv[1], "--help") == 0)
        usageErr("%s input-date-time in-format [out-format]\n", argv[0]);

    if (setlocale(LC_ALL, "") == NULL)
        errExit("setlocale");   /* Use locale settings in conversions */

    memset(&tm, 0, sizeof(struct tm));          /* Initialize 'tm' */
    if (strptime(argv[1], argv[2], &tm) == NULL)
        fatal("strptime");

    tm.tm_isdst = -1;           /* Not set by strptime(); tells mktime()
                                   to determine if DST is in effect */
    printf("calendar time (seconds since Epoch): %ld\n", (long) mktime(&tm));

    ofmt = (argc > 3) ? argv[3] : "%H:%M:%S %A, %d %B %Y %Z";
    if (strftime(sbuf, SBUF_SIZE, ofmt, &tm) == 0)
        fatal("strftime returned 0");
    printf("strftime() yields: %s\n", sbuf);

    exit(EXIT_SUCCESS);
}

执行结果:

如果输入两个参数,则函数strftime使用”%H:%M:%S %A, %d %B %Y %Z”形式,如果输入三个参数,函数strftime则使用输入的格式。

时区

在目录/usr/share/zoneinfo中,每个文件包含一个特定国家或地区内时区制度的相关信息,且往往根据其所描述的时区来加以命名,诸如EST 美国东部 CET欧洲中部 等。
系统的本地时间由时区文件/etc/localtime定义,通常链接到/usr/share/zoneinfo下的一个文件。
设置时区影响ctime() localtime() mktime() strftime(),为了获取当前的时区设置,上述函数都会调用tzset(3),对如下三个全局变量进行初始化:
char *tzname[2], int daylight; long timezone;
函数tzset会首先检查环境变量TZ,如果尚未设置该变量,则使用/etc/localtime中定义的默认时区来初始化时区.
程序执行结果:

root@ubuntu:~/tlpi-book/time# ./show_time 
ctime() of time() value is:  Sun Oct 22 23:03:27 2017
asctime() of local time is:  Sun Oct 22 23:03:27 2017
strftime() of local time is: Sunday, 22 October 2017, 23:03:27 CST
root@ubuntu:~/tlpi-book/time# 
root@ubuntu:~/tlpi-book/time# 
root@ubuntu:~/tlpi-book/time# TZ=":Pacific/Auckland" ./show_time
ctime() of time() value is:  Mon Oct 23 04:03:34 2017
asctime() of local time is:  Mon Oct 23 04:03:34 2017
strftime() of local time is: Monday, 23 October 2017, 04:03:34 NZDT
root@ubuntu:~/tlpi-book/time#  
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
《计算机图形学:原理与实践》第21章-动画 动画在计算机图形学中起着重要的作用,它可以通过计算机生成逼真的运动图像来模拟现实世界中的动态效果。第21章详细介绍了动画的原理和实践。 动画的目标是通过序列帧的播放来创造出连续的运动感。本章介绍了两种常见的动画制作方法:关键帧动画和插值动画。 关键帧动画是通过在时间轴上选择关键帧来定义动画的开始和结束状态,然后计算机会自动填充中间帧。这种方法可以减少制作动画的工作量,但帧与帧之间的过渡可能不够平滑。 插值动画则通过在关键帧之间插入中间帧来创建流畅的动画效果。其中,线性插值是最简单的方法,通过计算两个关键帧之间的过渡来生成中间帧。其他的插值方法还包括贝塞尔曲线插值和样条插值等,它们能够更好地保持物体的形态和运动特性。 此外,本章还介绍了动画中的常见技术,如运动模糊和骨骼动画。运动模糊通过在连续帧之间模糊对象来模拟物体的运动轨迹,使动画更加真实。骨骼动画则是通过在物体上添加骨骼和关节来模拟物体的形变和动作,从而实现更加灵活和逼真的动画效果。 此外,本章还介绍了动画中使用的额外技术,如动画蒙皮和递归动画。动画蒙皮是将物体的外表表面贴上一个虚拟的模型,使其能够更好地跟随物体的运动。递归动画则是通过将一个物体分解成多个部分,然后对每个部分进行独立的动画处理,最终合成整个物体的动画。 总而言之,《计算机图形学:原理与实践》第21章详细介绍了动画的原理和实践,包括关键帧动画、插值动画、运动模糊、骨骼动画、动画蒙皮和递归动画等技术。通过学习本章内容,读者可以更好地理解和应用计算机图形学中的动画技术。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值