欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

C語言如何實現(xiàn)Unix時間戳與本地時間轉(zhuǎn)化

 更新時間:2021年03月04日 14:38:04   作者:mill_li  
這篇文章主要介紹了C語言如何實現(xiàn)Unix時間戳與本地時間轉(zhuǎn)化的相關(guān)資料,文中通過示例代碼介紹的非常詳細,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧

前言

我們平常說時間都說的幾點幾分幾秒,星期幾,但是在計算機里面并不是直接使用我們所說的時間,而是使用Unix時間戳,這樣不管是哪個平臺,哪個系統(tǒng),都可以根據(jù)自己對時間的定義進行轉(zhuǎn)換,像Java,PHP等都提供了接口來進行轉(zhuǎn)化,C庫里面也有這樣的函數(shù),那具體是怎么實現(xiàn)的呢?要了解這個問題首先我們就必須要清楚什么是Unix時間戳,什么是我們平常使用的時間。

1. Unix時間戳

UNIX時間戳:Unix時間戳(英文為Unix epoch, Unix time, POSIX time 或 Unix timestamp)

是從1970年1月1日(UTC/GMT的午夜)開始所經(jīng)過的秒數(shù),不考慮閏秒。

UNIX時間戳的0按照ISO 8601規(guī)范為 :1970-01-01T00:00:00Z.

一個小時表示為UNIX時間戳格式為:3600秒;一天表示為UNIX時間戳為86400秒,閏秒不計算。

在大多數(shù)的UNIX系統(tǒng)中UNIX時間戳存儲為32位,這樣會引發(fā)2038年問題或Y2038。

對應(yīng)的時間和秒數(shù)如下

時間
1 分鐘 60 秒
1 小時 3600 秒
1 天 86400 秒
1 周 604800 秒
1 月 (30.44 天) 2629743 秒
1 年 (365.24 天) 31556926 秒

2. 本地時間

平常我們最常聽見的是陰歷和陽歷之分,陰歷是按照月亮的運行規(guī)律來計算日期的,那我們所說的陽歷又是什么呢?其實陽歷或者說叫西歷最早是叫做儒略歷,是由羅馬共和國獨裁官儒略·愷撒(即蓋烏斯·尤里烏斯·凱撒)采納數(shù)學(xué)家兼天文學(xué)家索西琴尼的計算后,于公元前45年1月1日起執(zhí)行的取代舊羅馬歷法的一種歷法,但令人遺憾的是,當(dāng)時那些頒發(fā)歷書的祭司們,卻不了解改歷的實質(zhì)。結(jié)果,可笑的是,當(dāng)時羅馬執(zhí)掌頒布歷書的祭司竟把原來歷法上規(guī)定的“每隔三年置閏”誤解為“每三年置一閏”。從公元前45年起,到公元前9年為止,這之間本應(yīng)設(shè)置10個閏年,他們卻設(shè)置了13個閏年。公元前9年,人們終于發(fā)現(xiàn)這一差錯,這時愷撒的外甥奧古斯都執(zhí)掌政權(quán),他糾正了這個錯誤,才停止了“三年一閏”。奧古斯都下令改正過來,改到次年(公元前8年)才置閏年。當(dāng)改正這種閏年的錯誤時已經(jīng)多閏了3年,為了去掉著多閏的3年,奧古斯都又下令停閏3年,即以公元前5年、公元前1年、公元前4年仍為平年,以后恢復(fù)了每4年一閏的規(guī)定了。奧古斯都為了宣揚這一功勞,仿效儒略·愷撒的做法,下令把自己出生的儒略歷中的8月改稱為奧古斯都月(這一名稱在西方沿用到今天)。8月后的大,小月份都翻轉(zhuǎn)過來了,9月為30天,10月為31天,11月為30天,12月為31天,這種置月方式一直沿用至今。如此一來,一年多出了一天,于是也從二月份29天里再減去一天,二月份只剩下28天了 1582年羅馬教皇格里高利對”儒略歷”又進行修改,規(guī)定被4整除的年為閏年,但逢百之年只有能被400除盡才能是閏年。這就是使用至今的“格里歷”。這樣做是為了使歷年與回歸年相接近。回歸年的周期是365.2425天。儒略歷一年的平均長度為365.25日,比回歸年(365.2425天)長11分14秒,自公元325年(該年采用儒略歷作為宗教日歷)積累到十六世紀(jì)末,春分日由3月21日提早到3月11日。于是羅馬教皇格里高利十三世(Gregorius XⅢ)于1582年10月4日還下令將次日(即原10月5日)定為10月15日,把春分日又恢復(fù)為3月21日。這樣,1582年的10月5日-14日這十天就成了“不存在”的日子,變?yōu)闅v史的空白。1949年9月27日,經(jīng)過中國人民政治協(xié)商會議第一屆全體會議通過,中華人民共和國使用國際社會多數(shù)國家通用的西歷和西元作為歷法和紀(jì)年。

3. 蔡勒公式

清楚了Unix時間戳和公歷的意義,怎么講秒數(shù)轉(zhuǎn)化成本地時間大家心里應(yīng)該有個大概了,既然本地時間知道了,那我們可不可以根據(jù)這個日期直接知道那一天是星期幾呢?數(shù)學(xué)家蔡勒(Zeller)推算出了這個公式,大家稱為蔡勒公式,使用這個公式隨便給出一個日期,就可以計算出是星期幾。

公式具體是這樣的

W = [C / 4] - 2C + y + [y / 4] + [13 * (M + 1) / 5] + d - 1

或者是:w = y + [y / 4] + [c / 4] - 2c + [26(m + 1) / 10] + d - 1

公式中的符號含義如下:

w:星期; w對7取模得:0-星期日,1-星期一,2-星期二,3-星期三,4-星期四,5-星期五,6-星期六

c:世紀(jì)-1(前兩位數(shù))

y:年(后兩位數(shù))

m:月(m大于等于3,小于等于14,即在蔡勒公式中,某年的1、2月要看作上一年的13、14月來計算,比如2003年1月1日要看作2002年的13月1日來計算)

d:日 [ ]代表取整,即只要整數(shù)部分。

下面以中華人民共和國成立100周年紀(jì)念日那天(2049年10月1日)來計算是星期幾,過程如下:

w = y + [y / 4] + [c / 4] - 2c + [26(m + 1) / 10] + d - 1

= 49 + [49 / 4] + [20 / 4] - 2 × 20 + [26 × (10 + 1) / 10] + 1 - 1

= 49 + [12.25] + 5 - 40 + [28.6]

= 49 + 12 + 5 - 40 + 28

= 54 (除以7余5)

即2049年10月1日(100周年國慶)是星期五。

再比如計算2006年4月4日,過程如下:

w = y + [y / 4] + [c / 4] - 2c + [26(m + 1) / 10] + d - 1

= 6 + [6 / 4] + [20 / 4] - 2 * 20 + [26 * (4 + 1) / 10] + 4 - 1

= -12 (除以7余5,注意對負數(shù)的取模運算!實際上應(yīng)該是星期二而不是星期五)

不過要注意的是,蔡勒公式只適合于1582年(明朝萬歷十年)10月15日之后的情形。

4. 具體實現(xiàn)

清楚了上面這些內(nèi)容,我們來看一下用C怎么實現(xiàn)Unix時間戳和本地時間的相互轉(zhuǎn)化,并根據(jù)指定的時間算出對應(yīng)的日期

#include <stdio.h>
#include <stdbool.h>

#define UTC_BASE_YEAR 1970
#define MONTH_PER_YEAR 12
#define DAY_PER_YEAR 365
#define SEC_PER_DAY 86400
#define SEC_PER_HOUR 3600
#define SEC_PER_MIN 60

/* 每個月的天數(shù) */
const unsigned char g_day_per_mon[MONTH_PER_YEAR] = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};

/* 自定義的時間結(jié)構(gòu)體 */
typedef struct
{
 unsigned short nYear;
 unsigned char nMonth;
 unsigned char nDay;
 unsigned char nHour;
 unsigned char nMin;
 unsigned char nSec;
 unsigned char DayIndex; /* 0 = Sunday */
} mytime_struct;

/*
 * 功能:
 * 判斷是否是閏年
 * 參數(shù):
 * year:需要判斷的年份數(shù)
 *
 * 返回值:
 * 閏年返回1,否則返回0
 */
unsigned char applib_dt_is_leap_year(unsigned short year)
{
 /*----------------------------------------------------------------*/
 /* Local Variables      */
 /*----------------------------------------------------------------*/

 /*----------------------------------------------------------------*/
 /* Code Body       */
 /*----------------------------------------------------------------*/
 if ((year % 400) == 0) {
 return 1;
 } else if ((year % 100) == 0) {
 return 0;
 } else if ((year % 4) == 0) {
 return 1;
 } else {
 return 0;
 }
}

/*
 * 功能:
 * 得到每個月有多少天
 * 參數(shù):
 * month:需要得到天數(shù)的月份數(shù)
 * year:該月所對應(yīng)的年份數(shù)
 *
 * 返回值:
 * 該月有多少天
 *
 */
unsigned char applib_dt_last_day_of_mon(unsigned char month, unsigned short year)
{
 /*----------------------------------------------------------------*/
 /* Local Variables      */
 /*----------------------------------------------------------------*/

 /*----------------------------------------------------------------*/
 /* Code Body       */
 /*----------------------------------------------------------------*/
 if ((month == 0) || (month > 12)) {
 return g_day_per_mon[1] + applib_dt_is_leap_year(year);
 }

 if (month != 2) {
 return g_day_per_mon[month - 1];
 } else {
 return g_day_per_mon[1] + applib_dt_is_leap_year(year);
 }
}

/*
 * 功能:
 * 根據(jù)給定的日期得到對應(yīng)的星期
 * 參數(shù):
 * year:給定的年份
 * month:給定的月份
 * day:給定的天數(shù)
 *
 * 返回值:
 * 對應(yīng)的星期數(shù),0 - 星期天 ... 6 - 星期六
 */
unsigned char applib_dt_dayindex(unsigned short year, unsigned char month, unsigned char day)
{
 char century_code, year_code, month_code, day_code;
 int week = 0;

 century_code = year_code = month_code = day_code = 0;

 if (month == 1 || month == 2) {
 century_code = (year - 1) / 100;
 year_code = (year - 1) % 100;
 month_code = month + 12;
 day_code = day;
 } else {
 century_code = year / 100;
 year_code = year % 100;
 month_code = month;
 day_code = day;
 }

 /* 根據(jù)蔡勒公式計算星期 */
 week = year_code + year_code / 4 + century_code / 4 - 2 * century_code + 26 * ( month_code + 1 ) / 10 + day_code - 1;
 week = week > 0 ? (week % 7) : ((week % 7) + 7);

 return week;
}

/*
 * 功能:
 * 根據(jù)UTC時間戳得到對應(yīng)的日期
 * 參數(shù):
 * utc_sec:給定的UTC時間戳
 * result:計算出的結(jié)果
 * daylightSaving:是否是夏令時
 *
 * 返回值:
 * 無
 */
void utc_sec_2_mytime(unsigned int utc_sec, mytime_struct *result, bool daylightSaving)
{
 /*----------------------------------------------------------------*/
 /* Local Variables      */
 /*----------------------------------------------------------------*/
 int sec, day;
 unsigned short y;
 unsigned char m;
 unsigned short d;
 unsigned char dst;

 /*----------------------------------------------------------------*/
 /* Code Body       */
 /*----------------------------------------------------------------*/

 if (daylightSaving) {
 utc_sec += SEC_PER_HOUR;
 }

 /* hour, min, sec */
 /* hour */
 sec = utc_sec % SEC_PER_DAY;
 result->nHour = sec / SEC_PER_HOUR;

 /* min */
 sec %= SEC_PER_HOUR;
 result->nMin = sec / SEC_PER_MIN;

 /* sec */
 result->nSec = sec % SEC_PER_MIN;

 /* year, month, day */
 /* year */
 /* year */
 day = utc_sec / SEC_PER_DAY;
 for (y = UTC_BASE_YEAR; day > 0; y++) {
 d = (DAY_PER_YEAR + applib_dt_is_leap_year(y));
 if (day >= d)
 {
  day -= d;
 }
 else
 {
  break;
 }
 }

 result->nYear = y;

 for (m = 1; m < MONTH_PER_YEAR; m++) {
 d = applib_dt_last_day_of_mon(m, y);
 if (day >= d) {
  day -= d;
 } else {
  break;
 }
 }

 result->nMonth = m;
 result->nDay = (unsigned char) (day + 1);
 /* 根據(jù)給定的日期得到對應(yīng)的星期 */
 result->DayIndex = applib_dt_dayindex(result->nYear, result->nMonth, result->nDay);
}

/*
 * 功能:
 * 根據(jù)時間計算出UTC時間戳
 * 參數(shù):
 * currTime:給定的時間
 * daylightSaving:是否是夏令時
 *
 * 返回值:
 * UTC時間戳
 */
unsigned int mytime_2_utc_sec(mytime_struct *currTime, bool daylightSaving)
{
 /*----------------------------------------------------------------*/
 /* Local Variables      */
 /*----------------------------------------------------------------*/
 unsigned short i;
 unsigned int no_of_days = 0;
 int utc_time;
 unsigned char dst;

 /*----------------------------------------------------------------*/
 /* Code Body       */
 /*----------------------------------------------------------------*/
 if (currTime->nYear < UTC_BASE_YEAR) {
 return 0;
 }

 /* year */
 for (i = UTC_BASE_YEAR; i < currTime->nYear; i++) {
 no_of_days += (DAY_PER_YEAR + applib_dt_is_leap_year(i));
 }

 /* month */
 for (i = 1; i < currTime->nMonth; i++) {
 no_of_days += applib_dt_last_day_of_mon((unsigned char) i, currTime->nYear);
 }

 /* day */
 no_of_days += (currTime->nDay - 1);

 /* sec */
 utc_time = (unsigned int) no_of_days * SEC_PER_DAY + (unsigned int) (currTime->nHour * SEC_PER_HOUR +
        currTime->nMin * SEC_PER_MIN + currTime->nSec);

 if (dst && daylightSaving) {
 utc_time -= SEC_PER_HOUR;
 }

 return utc_time;
}

int main(int argc, char *argv[])
{
 mytime_struct my_time;
 unsigned int sec;
 char *DayIndex[] = {"Sun.", "Mon.", "Tues.", "Wed.", "Thur.", "Fri.", "Sat."};

 /* 這里根據(jù)UTC時間戳計算出來的時間是零時區(qū)的時間,所以如果要轉(zhuǎn)化成北京時間就需要多加8小時 */
 utc_sec_2_mytime(1484537668 + 8 * SEC_PER_HOUR, &my_time, false);


 printf("%d-%d-%d %d:%d:%d %s\n", my_time.nYear, my_time.nMonth, my_time.nDay,
  my_time.nHour, my_time.nMin, my_time.nSec, DayIndex[my_time.DayIndex]);

 sec = mytime_2_utc_sec(&my_time, false);
 printf("sec = %d\n", sec);

 return 0;
}

基本上的內(nèi)容就這些了,平常最好能夠直接使用系統(tǒng)提供的接口,如果不能使用的話就自己實現(xiàn),根據(jù)上面的代碼修改成自己需要的,如果有不對的地方,希望能夠批評指正

參考文獻

http://www.dbjr.com.cn/article/206868.htm

總結(jié)

到此這篇關(guān)于C語言如何實現(xiàn)Unix時間戳與本地時間轉(zhuǎn)化的文章就介紹到這了,更多相關(guān)C語言Unix時間戳內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • 詳解C語言隨機數(shù)設(shè)置的三種方式(保姆級教程)

    詳解C語言隨機數(shù)設(shè)置的三種方式(保姆級教程)

    本篇文章將為大家介紹在C語言中設(shè)置隨機數(shù)的三大方法的使用,文中的示例代碼講解詳細,對我們學(xué)習(xí)C語言有一定的幫助,需要的可以參考一下
    2022-11-11
  • C語言實現(xiàn)自行車管理系統(tǒng)

    C語言實現(xiàn)自行車管理系統(tǒng)

    這篇文章主要為大家詳細介紹了C語言實現(xiàn)自行車管理系統(tǒng),文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2022-08-08
  • 10行C++代碼實現(xiàn)高性能HTTP服務(wù)

    10行C++代碼實現(xiàn)高性能HTTP服務(wù)

    這篇文章主要介紹了10行C++代碼如何實現(xiàn)高性能HTTP服務(wù),幫助大家更好的理解和學(xué)習(xí)使用c++,感興趣的朋友可以了解下
    2021-04-04
  • C語言使用DP動態(tài)規(guī)劃思想解最大K乘積與乘積最大問題

    C語言使用DP動態(tài)規(guī)劃思想解最大K乘積與乘積最大問題

    Dynamic Programming動態(tài)規(guī)劃方法采用最優(yōu)原則來建立用于計算最優(yōu)解的遞歸式,并且考察每個最優(yōu)決策序列中是否包含一個最優(yōu)子序列,這里我們就來展示C語言使用DP動態(tài)規(guī)劃思想解最大K乘積與乘積最大問題
    2016-06-06
  • 基于MFC實現(xiàn)自定義復(fù)選框效果

    基于MFC實現(xiàn)自定義復(fù)選框效果

    復(fù)選框是一種可同時選中多項的基礎(chǔ)控件,主要是有兩種明顯的狀態(tài):選中與非選中。本文將通過MFC框架實現(xiàn)自定義復(fù)選框效果,感興趣的可以了解一下
    2022-02-02
  • C語言實現(xiàn)電話簿項目

    C語言實現(xiàn)電話簿項目

    這篇文章主要為大家詳細介紹了C語言實現(xiàn)電話簿項目,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2019-12-12
  • C++超細致講解隊列queue的使用

    C++超細致講解隊列queue的使用

    隊列先進先出,即只能在容器的末尾添加新元素,只能從頭部移除元素,下面這篇文章主要給大家介紹了關(guān)于C++中隊列queue用法的相關(guān)資料,文中通過示例代碼介紹的非常詳細,需要的朋友可以參考下
    2022-05-05
  • C語言靜態(tài)版通訊錄的設(shè)計與實現(xiàn)

    C語言靜態(tài)版通訊錄的設(shè)計與實現(xiàn)

    靜態(tài)版通訊錄是一種簡單的通訊錄實現(xiàn)方式,通過定義固定的數(shù)組大小來存儲聯(lián)系人信息。該方法不支持動態(tài)增刪聯(lián)系人,但具有實現(xiàn)簡單、易于理解的優(yōu)點。在程序設(shè)計中,需注意數(shù)組邊界溢出等問題
    2023-04-04
  • C++設(shè)計模式之職責(zé)鏈模式

    C++設(shè)計模式之職責(zé)鏈模式

    這篇文章主要介紹了C++設(shè)計模式之職責(zé)鏈模式,本文講解了什么是職責(zé)鏈模式、什么場合下使用、代碼實例等內(nèi)容,需要的朋友可以參考下
    2014-10-10
  • 用C語言實現(xiàn)排雷游戲

    用C語言實現(xiàn)排雷游戲

    大家好,本篇文章主要講的是用C語言實現(xiàn)排雷游戲,感興趣的同學(xué)趕快來看一看吧,對你有幫助的話記得收藏一下
    2022-01-01

最新評論