最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

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

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

前言

我們平常說時間都說的幾點幾分幾秒,星期幾,但是在計算機里面并不是直接使用我們所說的時間,而是使用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。

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

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

2. 本地時間

平常我們最常聽見的是陰歷和陽歷之分,陰歷是按照月亮的運行規(guī)律來計算日期的,那我們所說的陽歷又是什么呢?其實陽歷或者說叫西歷最早是叫做儒略歷,是由羅馬共和國獨裁官儒略·愷撒(即蓋烏斯·尤里烏斯·凱撒)采納數(shù)學家兼天文學家索西琴尼的計算后,于公元前45年1月1日起執(zhí)行的取代舊羅馬歷法的一種歷法,但令人遺憾的是,當時那些頒發(fā)歷書的祭司們,卻不了解改歷的實質(zhì)。結(jié)果,可笑的是,當時羅馬執(zhí)掌頒布歷書的祭司竟把原來歷法上規(guī)定的“每隔三年置閏”誤解為“每三年置一閏”。從公元前45年起,到公元前9年為止,這之間本應設置10個閏年,他們卻設置了13個閏年。公元前9年,人們終于發(fā)現(xiàn)這一差錯,這時愷撒的外甥奧古斯都執(zhí)掌政權(quán),他糾正了這個錯誤,才停止了“三年一閏”。奧古斯都下令改正過來,改到次年(公元前8年)才置閏年。當改正這種閏年的錯誤時已經(jīng)多閏了3年,為了去掉著多閏的3年,奧古斯都又下令停閏3年,即以公元前5年、公元前1年、公元前4年仍為平年,以后恢復了每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年(該年采用儒略歷作為宗教日歷)積累到十六世紀末,春分日由3月21日提早到3月11日。于是羅馬教皇格里高利十三世(Gregorius XⅢ)于1582年10月4日還下令將次日(即原10月5日)定為10月15日,把春分日又恢復為3月21日。這樣,1582年的10月5日-14日這十天就成了“不存在”的日子,變?yōu)闅v史的空白。1949年9月27日,經(jīng)過中國人民政治協(xié)商會議第一屆全體會議通過,中華人民共和國使用國際社會多數(shù)國家通用的西歷和西元作為歷法和紀年。

3. 蔡勒公式

清楚了Unix時間戳和公歷的意義,怎么講秒數(shù)轉(zhuǎn)化成本地時間大家心里應該有個大概了,既然本地時間知道了,那我們可不可以根據(jù)這個日期直接知道那一天是星期幾呢?數(shù)學家蔡勒(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:世紀-1(前兩位數(shù))

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

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

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

下面以中華人民共和國成立100周年紀念日那天(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ù)的取模運算!實際上應該是星期二而不是星期五)

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

4. 具體實現(xiàn)

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

#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:該月所對應的年份數(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ù)給定的日期得到對應的星期
 * 參數(shù):
 * year:給定的年份
 * month:給定的月份
 * day:給定的天數(shù)
 *
 * 返回值:
 * 對應的星期數(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時間戳得到對應的日期
 * 參數(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ù)給定的日期得到對應的星期 */
 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://m.fzitv.net/article/206868.htm

總結(jié)

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

相關(guān)文章

  • C++?pthread入門指南

    C++?pthread入門指南

    pthread是C++98接口且只支持Linux,使用時需要包含頭文件#include?<pthread.h>,編譯時需要鏈接pthread庫,其中p是POSIX的縮寫,而POSIX是Portable?Operating?System?Interface的縮寫,這篇文章主要介紹了C++?pthread簡介,需要的朋友可以參考下
    2024-05-05
  • C++連接mysql數(shù)據(jù)庫并讀取數(shù)據(jù)的具體步驟

    C++連接mysql數(shù)據(jù)庫并讀取數(shù)據(jù)的具體步驟

    在實際開發(fā)中我們經(jīng)常需要對數(shù)據(jù)庫進行訪問,針對不同類型的數(shù)據(jù)庫(如MySQL、sqLite、Access、Excel等),如果采用不同的方法進行連接,會把我們搞崩潰,下面這篇文章主要給大家介紹了關(guān)于C++連接mysql數(shù)據(jù)庫并讀取數(shù)據(jù)的具體步驟,需要的朋友可以參考下
    2023-04-04
  • C++ 實現(xiàn)旋轉(zhuǎn)蛇錯覺的詳細代碼

    C++ 實現(xiàn)旋轉(zhuǎn)蛇錯覺的詳細代碼

    這篇文章主要介紹了C++ 實現(xiàn)旋轉(zhuǎn)蛇錯覺的詳細代碼,代碼簡單易懂,對大家的學習或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2021-09-09
  • c++字符串分割的方法

    c++字符串分割的方法

    這篇文章主要介紹了c++字符串分割的方法,幫助大家更好的理解和學習c++,感興趣的朋友可以了解下
    2020-08-08
  • C++ push方法與push_back方法的使用與區(qū)別

    C++ push方法與push_back方法的使用與區(qū)別

    這篇文章主要介紹了C++ push方法與push_back方法的使用與區(qū)別,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2019-12-12
  • Qt6.0開發(fā)環(huán)境搭建步驟(圖文)

    Qt6.0開發(fā)環(huán)境搭建步驟(圖文)

    這篇文章主要介紹了Qt6.0開發(fā)環(huán)境搭建步驟(圖文),文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2021-03-03
  • c語言文件讀寫示例(c語言文件操作)

    c語言文件讀寫示例(c語言文件操作)

    這篇文章主要介紹了c語言文件讀寫示例(c語言文件操作),需要的朋友可以參考下
    2014-02-02
  • C語言深入探究棧的原理

    C語言深入探究棧的原理

    一種特殊的線性表,其只允許在固定的一端進行插入和刪除元素操作。進行數(shù)據(jù)插入和刪除操作的一端 稱為棧頂,另一端稱為棧底。棧中的數(shù)據(jù)元素遵守后進先出LIFO(Last In First Out)的原則
    2021-11-11
  • C語言數(shù)據(jù)結(jié)構(gòu)算法基礎之循環(huán)隊列示例

    C語言數(shù)據(jù)結(jié)構(gòu)算法基礎之循環(huán)隊列示例

    這篇文章主要為大家介紹了C語言數(shù)據(jù)結(jié)構(gòu)算法基礎之循環(huán)隊列,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪
    2022-06-06
  • Mingw64編譯wxWidgets 3.0.2常見錯誤分析

    Mingw64編譯wxWidgets 3.0.2常見錯誤分析

    這篇文章主要介紹了Mingw64編譯wxWidgets 3.0.2常見錯誤分析,需要的朋友可以參考下
    2016-11-11

最新評論

松江区| 桂阳县| 天全县| 正安县| 泸州市| 绥芬河市| 澄江县| 邮箱| 昌邑市| 福安市| 筠连县| 荣成市| 龙州县| 奉贤区| 衡东县| 思茅市| 姚安县| 乌兰察布市| 沐川县| 新和县| 龙岩市| 秦皇岛市| 澄城县| 临西县| 邢台县| 郁南县| 武陟县| 长春市| 云浮市| 旺苍县| 休宁县| 济南市| 建宁县| 双峰县| 当雄县| 叙永县| 马边| 无极县| 拜城县| 秭归县| 遵化市|