聊聊時間(3)UTC時間轉UNIX時間戳

2022-01-26 樂創客

前一篇文章《聊聊時間(2)UNIX時間戳轉UTC時間》中,我們詳細地解釋了如何將一個32位無符號的UNIX時間戳利用軟體算法轉換成我們可以看得懂的UTC時間。我們說,在STM32F10x系列無萬年曆功能的RTC系統中,如果要將RTC中的計數值顯示出來,那麼需要利用UNIX時間戳轉UTC時間算法。但是如果需要設置一個時鐘的時間,那還需要先將當前時區的時間轉換成UTC時間,再將UTC時間轉換成UNIX時間戳寫入RTC的32位寄存器中。今天的文章,我們就來聊聊如何將UTC時間轉換成UNIX時間戳。

   UTC時間轉換成UNIX時間戳

UTC時間轉換成UNIX時間戳的方法其實很簡單,因為此條件下輸入的年月日是固定的。因此對於這個問題,我們可以直接按照年月日時分的形式進行計算,統計每它們的秒數之和。最後加入最後的秒數就可以得到當前的UNIX時間戳了。我們知道閏年的秒數為31622400s,平年的秒數為31536000s。

程序的設計思路為:

(1)統計從1970年至今一共過了多少平年,多少閏年,統計完成之後,根據閏年和平年的秒數計算出從1970年1月1日至今年一共經過了多少秒。這一部分的代碼如圖1所示。

圖1 閏年和平年秒數轉換

(2)計算出當前年份是平年還是閏年,以此推算出從年初到上個月過去了多少天。計算完成之後,可以將本月的到昨天的天數一起統計進來,最終可以將年月日三個單位的秒數一起統計出來。具體代碼如圖2所示。

圖2 月和日轉換成UNIX時間戳秒數

(3)將剩餘的時分秒利用同樣的方式進行累加,最終得出當前的UNIX時間戳。其最終的代碼如圖3所示。

圖3 最終完成的代碼。

我們可以簡單做個測試,將日期設置成2021年2月5日8時6分7秒,運行程序計算出當前的UNIX時間戳為1612512367s,再將1612512367s時間戳輸入到我們上一篇文章中UNIX時間戳轉UTC時間的代碼裡,看看最終結果,如圖4所示。

圖4 UNIX時間戳和UTC時間互相轉換

由圖4可知,我們的測試結果完全正確。當然對於這種計算比較繁瑣的程序,可以使用單元測試全部測試一遍,以排除深層的BUG。

   本文全部代碼:

1.timex_test.c

#include <stdio.h>#include "timex_test1.h"time_tt stCurrentTime;int main(void){  stCurrentTime.year = 2021;  stCurrentTime.month = 2;  stCurrentTime.date = 5;  stCurrentTime.hour = 8;  stCurrentTime.minute = 6;  stCurrentTime.second = 7;  printf("%ds", UTCToUnixTimeStamp(&stCurrentTime));  return 0;}UnixTimeStamp_t UTCToUnixTimeStamp(time_tt *time){  int FlatYearMonthDay[13] = {0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};  int LeapYearMonthDay[13] = {0, 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};  time_tt *tempTime;             int i;  tempTime = time;              int LeapYearNumber;              int FlatYearNumber;              int ThisYear;  int LastMonDays = 0;  UnixTimeStamp_t TimeStamp = 0;
for ( i = UNIX_TIME_STAMP_YEAR; i < tempTime->year; i ++ ) { if((((i % 4) == 0) && ((i % 100) != 0)) || ((i % 400) == 0)) { LeapYearNumber ++; } else { FlatYearNumber ++; } } TimeStamp = LeapYearNumber * 31622400 + FlatYearNumber * 31536000;
if((((tempTime->year % 4) == 0) && ((tempTime->year % 100) != 0)) || ((tempTime->year % 400) == 0)) { ThisYear = LEAP_YEAR; } else { ThisYear = FLAT_YEAR; }
for ( i = 1; i < tempTime->month; i ++) { if(ThisYear == LEAP_YEAR) { LastMonDays += LeapYearMonthDay[i]; } else if(ThisYear == FLAT_YEAR) { LastMonDays += FlatYearMonthDay[i]; } } LastMonDays = LastMonDays + tempTime->date - 1; TimeStamp += LastMonDays * 86400;
TimeStamp += tempTime->hour * 3600; TimeStamp += tempTime->minute * 60; TimeStamp += tempTime->second; return TimeStamp;}

2.timex_test.h

#ifndef __TIMEX_TEST1_H_#define __TIMEX_TEST1_H_
#define UNIX_TIME_STAMP_YEAR 1970#define LEAP_YEAR 1#define FLAT_YEAR 0typedef struct { int year; int month; int date; int hour; int minute; int second;} time_tt;
typedef unsigned int UnixTimeStamp_t;

UnixTimeStamp_t UTCToUnixTimeStamp(time_tt *time);#endif

相關焦點

  • 什麼是Unix時間戳(Unix timestamp)
    在不同程式語言中實現Unix時間戳(Unix timestamp) → 普通時間Unix時間戳(Unix timestamp),或稱Unix時間(Unix time)、POSIX時間(POSIX time),是一種時間表示方式,定義為從格林威治時間1970年01月01日00時00分00秒起至現在的總秒數。
  • UNIX時間戳和北京時間的相互轉換
    什麼是時間戳準確的說,應該是unix時間戳,是從1970年1月1日(UTC/GMT的午夜)開始所經過的秒數,不考慮閏秒。一個小時表示為UNIX時間戳格式為:3600秒;一天表示為UNIX時間戳為86400秒,閏秒不計算。
  • 生信伺服器 | Linux 時間戳和標準時間
    在 Linux 系統中,有許多場合都使用時間戳的方式表示時間,即從1970年1月1日起至當前的天數或秒數。如/etc/shadow裡的密碼更改日期和失效日期,還有代理伺服器的訪問日誌對訪問時間的記錄等等。
  • 一學就會的 Python 時間轉化總結(超全)
    不同的情況會遇到不同的時間問題:具體時間點、時間間隔、星期等,無時不刻我們在和時間碰撞。本文將利用Python對時間相關的類,及其方法與屬性等進行詳細的講解1. 時間戳 1.1時間戳簡介在正式講解時間的相關函數之前,我們必須先一個概念:時間戳。本文中特指unix時間戳。
  • 地球時間和 C++ 時間庫
    根據表示的精確度的不同,Unix時間戳有秒級(time_t)、毫秒級(timeval)、納秒級(timespec)等。Unix和UTC不完全一致,UTC規範的閏秒表示為 2016-12-31 23:59:60 UTC,而 Unix time 會重複兩個 23:59:59 時刻。
  • Python 處理日期與時間的全面總結!
    獲取當前時間和轉化時間格式time() 返回時間戳格式的時間 (相對於1.1 00:00:00以秒計算的偏移量)ctime() 返回字符串形式的時間,可以傳入時間戳格式時間,用來做轉化asctime() 返回字符串形式的時間,可以傳入struct_time形式時間,用來做轉化localtime() 返回當前時間的struct_time
  • Python | 時間戳轉換
    像上圖中的beginbidtime變量,這是時間戳。時間戳是啥?是指格林威治時間自 1970 年 1 月 1 日(00:00:00 GMT)(一般把這個時點稱為 unix 紀元或 POSIX 時間)至當前時間的總秒數。時間戳的好處是能夠唯一地表示某一刻的時間,但這顯然不利於肉眼觀察和分析數據,所以下面我們將時間戳轉化為常見的時間格式。2.
  • Python 處理日期與時間的全面總結(7000字)
    獲取當前時間和轉化時間格式time() 返回時間戳格式的時間 (相對於1.1 00:00:00以秒計算的偏移量)ctime() 返回字符串形式的時間,可以傳入時間戳格式時間,用來做轉化asctime() 返回字符串形式的時間,可以傳入struct_time形式時間,用來做轉化localtime() 返回當前時間的struct_time
  • PHP時間戳和日期相互轉換操作
    1. php中時間轉換函數strtotime(date("Y-m-d H:i"))date("Y-m-d H:i",$unixtime)2. php中獲得今天零點的時間戳 要獲得零點的unix時間戳,可以使用$todaytime=strtotime(
  • Pandas 時間序列 - 縱覽與時間戳
    時間序列縱覽時間戳 vs.時間段轉換時間戳提供格式參數用多列組合日期時間無效數據紀元時間戳把時間戳轉換為紀元應用 `origin` 參數生成時間戳範圍自定義頻率範圍時間戳的界限依託 NumPy 的 datetime64、timedelta64 等數據類型,pandas 可以處理各種時間序列數據,還能調用 scikits.timeseries 等 Python 支持庫的時間序列功能。
  • 深度乾貨:python中時間表示
    時間戳,epoch,utc三者之間的關係如下圖所示:3,DST, tzone儘管我們已經可以精確地表示一個時間,很多情況下,我們還是要根據地區實際情況對時間進行一個調整,最常見的就是時區,tzone,相信大家都比較熟悉。
  • python基礎:Python3時間戳轉換為指定格式的日期
    在寫Python的時候經常會遇到時間格式的問題,首先就是最近用到的時間戳(timestamp)和時間字符串之間的轉換。
  • (基礎篇)PHP獲取時間、時間戳的各種格式寫法匯總
    date()很簡單,這就是獲取時間的方法,格式為:date($format, $timestamp),format為格式、timestamp為時間戳–可填參數。2、獲取時間戳方法time()、strtotime()這兩個方法,都可以獲取php中unix時間戳,time()為直接獲取得到,strtotime($time, $now)為將時間格式轉為時間戳,$time為必填。清楚了這個,想了解更多,請繼續往下看。
  • ClickHouse入坑指南——時間日期函數
    SELECT toDateTime('2019-01-01 00:00:00', 'UTC') AS time_utc, toTypeName(time_utc) AS type_utc, toInt32(time_utc) AS int32utc, toTimeZone(time_utc, 'Asia/Yekaterinburg
  • 時間戳
    什麼是時間戳在FDA 21 CFR §11.10(e)有提到時間戳(time-stamped)(e) Use ofsecure
  • 數據分析——常用SQL日期及時間函數匯總(收藏備查)
    之前分享過《SQL窗口函數》,今天分享一些常用的時間日期相關的函數。
  • 【基礎】UNIX時間戳2種轉換(oracle函數、python))
    一、場景    在開發中,我們經常遇到時間戳轉換日期或者日期轉換時間戳;比如與企業微信接口在拉取打卡信息的時候就需要時間戳
  • python操作日期和時間的方法
    1、將字符串的時間轉換為時間戳代碼如下:a = "2013-10-10 23:40:00"import timetimeArray = time.strptime(a, "%Y-%m-%d %H:%M:%S")timeStamp = int(time.mktime(timeArray))timeStamp == 1381419600
  • MySQL日期、時間函數總結
    看下面的例子就明白了:mysql> select now(), sleep(3), sysdate();+-++-+| now() | sleep(3) | sysdate() |+-++-+| 2021-08-08 22:28:21 | 0 | 2008-08-08 22:28:24 |+-++-+sysdate()日期時間函數
  • 比特幣時間戳的安全性
    比特幣通常被稱為一種安全的時間戳服務。我們從未獲得過一種帶有可信時間戳的全球性真實記錄,那麼這是怎麼產生的呢?這主要是得益於工作量證明與礦工必須遵守的一些簡單規則的結合。如果您考慮一下敵對礦工可能會如何嘗試擴展可接受的時間戳窗口,很明顯,無論他有多少算力,他都無法將時間戳推遲超過2小時。