【小沐学C++】C++17 实现日期和时间相关编程

文章目录

  • 1、简介
    • 1.1 GMT
    • 1.2 UT
    • 1.3 CST
    • 1.4 ISO
    • 1.5 UTC
    • 1.6 Unix 时间戳
  • 2、C++语言的时间函数
    • 2.1 获取当前时间
    • 2.2 计算时间差
    • 2.3 UTC时间与本地时间
    • 2.4 chrono库
  • 3、其他语言的时间函数
    • 3.1 Java
    • 3.2 JavaScript
    • 3.3 Microsoft .NET / C#
    • 3.4 MySQL
    • 3.5 PHP
    • 3.6 PostgreSQL
    • 3.7 Python
    • 3.8 Ruby
    • 3.9 SQL Server
    • 3.10 VBScript / ASP
  • 4、时间的课外知识点
    • 4.1 四季
    • 4.2 十二时辰
    • 4.3 二十四时区
  • 结语

1、简介

时间(Time)是物质的永恒运动、变化的持续性、顺序性的表现,包含时刻和时段两个概念。时间是人类用以描述物质运动过程或事件发生过程的一个参数,确定时间,是靠不受外界影响的物质周期变化的规律。以地球自转为基础的时间计量系统称为世界时系统。时、日、月、年、世纪的时间计量属天文学中的历法范畴。时间是物理学中的七个基本物理量之一,符号为t。在国际单位制(SI)中,时间的基本单位是秒,符号为s。

【小沐学C++】C++17 实现日期和时间相关编程_第1张图片
时间是物理学中的七个基本物理量之一,符号为t。在国际单位制(SI)中,时间的基本单位是秒,符号为s。
【小沐学C++】C++17 实现日期和时间相关编程_第2张图片

1.1 GMT

GMT:Greenwich Mean Time 格林尼治标准时间。这是以英国格林尼治天文台观测结果得出的时间,这是英国格林尼治当地时间,这个地方的当地时间过去被当成世界标准的时间。
【小沐学C++】C++17 实现日期和时间相关编程_第3张图片

1.2 UT

UT:Universal Time 世界时。根据原子钟计算出来的时间。

1.3 CST

CST可视为美国、澳大利亚、古巴或中国的标准时间。
CST可以为如下4个不同的时区的缩写:
美国中部时间:Central Standard Time (USA) UT-6:00
澳大利亚中部时间:Central Standard Time (Australia) UT+9:30
中国标准时间:China Standard Time UT+8:00
古巴标准时间:Cuba Standard Time UT-4:00
【小沐学C++】C++17 实现日期和时间相关编程_第4张图片

1.4 ISO

ISO:是一种时间的表示方法。

1.5 UTC

UTC:Coordinated Universal Time 协调世界时。因为地球自转越来越慢,每年都会比前一年多出零点几秒,每隔几年协调世界时组织都会给世界时+1秒,让基于原子钟的世界时和基于天文学(人类感知)的格林尼治标准时间相差不至于太大。并将得到的时间称为UTC,这是现在使用的世界标准时间。

协调世界时,又称世界统一时间、世界标准时间、国际协调时间。由于英文(CUT)和法文(TUC)的缩写不同,作为妥协,简称UTC。

协调世界时是以原子时秒长为基础,在时刻上尽量接近于世界时的一种时间计量系统。中国大陆采用ISO 8601-1988的《数据元和交换格式信息交换日期和时间表示法》(GB/T 7408-1994)称之为国际协调时间,代替原来的GB/T 7408-1994;中国台湾采用CNS 7648的《资料元及交换格式–资讯交换–日期及时间的表示法》,称之为世界统一时间。

YYYYMMDD T HHMMSS Z(或者时区标识)。
举例1:2016-08-9T10:01:54.123Z,表示UTC时间,世界标准时间
举例2:20100607T152000Z,表示2010年6月7号15点20分0秒,Z表示是UTC时间
举例3:20100607T152000+08,其中 “+08” 表示东八区。表示北京时间。

协调世界时不与任何地区位置相关,也不代表此刻某地的时间,所以在说明某地时间时要加上时区也就是说GMT并不等于UTC,而是等于UTC+0,只是格林尼治刚好在0时区上。GMT = UTC+0

UTC是我们现在用的时间标准,GMT是老的时间计量标准。UTC是根据原子钟来计算时间,而GMT是根据地球的自转和公转来计算时间,也就是太阳每天经过位于英国伦敦郊区的皇家格林威治天文台的时间就是中午12点。

北京时间:2021-01-31 00:00:00对应的国际标准时间格式为:2021-01-30T16:00:00.000Z

UTC 是标准时间参照,GMT(格林威治时间)、CST(北京时间)、PST(太平洋时间)等是具体的时区。由于 UTC +0 的特殊性,所以有时也把 GMT 当成参照。UTC(Coordinated Universal Time协调世界时)是个标准时间,GMT(Greenwich Mean Time,格林威治时间)是时区时间。UTC作为一个标准时间和各个时区时间换算。

日期和时间通过大写字母 T 来分隔。
UTC 时间通过大写字母 Z 来定义。最末尾的Z表示UTC统一时间。
如果您希望修改相对于 UTC 的时间,请删除 Z 并用 +HH:MM 或 -HH:MM 代替:

var d = new Date("2018-02-19T12:00:00");
var d = new Date("2018-02-19T12:00:00-08:30");
String date = "2021-01-30T16:00:00.000Z";
date = date.replace("Z", " UTC");
SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS Z");
Date d = format.parse(date);

说明:
gmt是前世界标准时,utc是现世界标准时。
GMT和UTC时间可以认为是一样的, 只不过utc更加精准.

(1)时间字符串尾部加Z 表示UTC。+0800表示加上8时区, 也即本地时间。 (2)为了操作方便,时间字符串的格式应该写为: 2020/02/22 10:00:00 这样的格式。 (3)年月日中间用横杠连接且没有指定时分秒则默认表示UTC时间. 可以指定UTC+0800表示时间字符串格式。 (4)时分秒后面加Z表示UTC时间, 不指定Z则表示本地时间。为了防止出错, 建议年月日中间用斜杠‘/’连接。
  • 当前系统时间 UTC 时间 转换
#include
#include
using namespace std;

int main(){
	time_t  now =time(0);
	char  * data = ctime(&now)
	
	cout << now  <<endl;  //输出一个时间戳,1970年1月1日以来经过的秒数。如果系统没有时间,则返回 .1。
	cout << data <<endl;  //字符串时间  
	
	//转换UTC时间
	//  tm *gmtime(const time_t *time);  该函数返回一个指向 time 的指针,time 为 tm 结构,用协调世界时(UTC)也被称为格林尼治标准时间(GMT)表示。
	tm  * gm =gmtime(&now);
	// char * asctime ( const struct tm * time );  该函数返回一个指向字符串的指针,字符串包含了 time 所指向结构中存储的信息,返回形式为:day month date hours:minutes:seconds year\n\0。
	data = asctime(gm);
	cout << data <<endl;   //UTC 时间  
	return 0;
}
(1)当前的UTC时间 是从 1970年01月01日 0:00:00 开始到现在所相差的秒数. 如果需要转换为日期, 那么需要通过函数进行转换。 (2)C标准库里的time_t类型, 它代表一个秒数, 从 1970.1.1 00:00 开始到 time_t所代表的时间的间隔的秒数。 (3)C标准库里的日期时间结构体,需要注意的 tm_year 是从1900开始的年份差, 如果需要得到实际的年份,需要+1900。
int TestTime()
{
	// 获取当前时间的 UTC 秒数.
	time_t now;
	time(&now);

	std::cout << "now: " << now << std::endl;

	auto PrintDate = [](struct tm* ttm,const char* key)->char*{
		char buf[32] = {0};
		sprintf(buf, "%.4d-%.2d-%.2d %.2d:%.2d:%.2d", ttm->tm_year+1900,
				ttm->tm_mon + 1, ttm->tm_mday, ttm->tm_hour, ttm->tm_min,
				ttm->tm_sec);
		std::cout <<  key  <<" date: " << buf << std::endl;
		return strdup(buf);
	};

	// 把UTC时间转换为 tm 结构体, 注意不是本地时间,是世界统一时间,全时间的时间都一样.
	struct tm utc_tm1 = *gmtime(&now);
	auto utc_str = PrintDate(&utc_tm1,"utc");

	// 本地日期, 也就是当前时区的日期.
	auto local_t1 = localtime(&now);
	PrintDate(local_t1,"local");

	// 知道UTC的日期转换为本地日期
	time_t tt = _mkgmtime64(&utc_tm1);
	auto local_t2 = localtime(&tt);
	PrintDate(local_t2,"utc->local");

	// 知道本地日期转换为UTC日期
	auto utc_time = mktime(local_t1);
	auto ttm1 = gmtime(&utc_time);
	PrintDate(ttm1,"local->utc");

	return 0;
}
  • nodejs的UTC时间接口:
let date = new Date()

// 直接打印当前时间
console.log(date); // 2021-12-09T08:58:34.625Z

// 获取时间戳
console.log(date.getTime()); // 1639040314625

// 获取本地时间,当前是几点
console.log(date.getHours()); // 16

// 获取UTC标准时间,当前是几点
console.log(date.getUTCHours()); // 8

// 获取 UTC标准时间 与 本地时区 之间的时差,单位是分钟
console.log(date.getTimezoneOffset()); // -480  480/60 = 8h,相当于比UTC标准时间差了 

console.log( 'default: ', date )
console.log( 'toISOString: ', date.toISOString() )
console.log( 'toUTCString: ', date.toUTCString() )
console.log( 'toLocaleString: ', date.toLocaleString() )
console.log( 'toLocaleDateString: ', date.toLocaleDateString() )
console.log( 'toString: ', date.toString() )
console.log( 'toTimeString: ', date.toTimeString() )
console.log( 'toDateString: ', date.toDateString() )
console.log( 'toJSON: ', date.toJSON() )
console.log( 'toGMTString: ', date.toGMTString() )

【小沐学C++】C++17 实现日期和时间相关编程_第5张图片

1.6 Unix 时间戳

时间戳:是指格林威治时间1970年01月01日00时00分00秒(北京时间1970年01月01日08时00分00秒)起至现在的总秒数。
时间字符串:形如2021-12-01 12:00:00

这是基于 UTC 1970.01.01 00:00:00 到现在的总秒数/毫秒数,所以这个总秒数/毫秒数全世界都是一样的,也就是说 Unix 时间戳和时区无关,你可以在两个不同时区的服务器执行以下 Java 代码来验证,得出的结果是相同的。System.currentTimeMills();

  • 时间戳转时间字符串(strftime)
#include 
#include 
#include 
using namespace std;

string convertTimeStamp2TimeStr(time_t timeStamp){
    struct tm *timeinfo = nullptr;
    char buffer[80];
    timeinfo = localtime(&timeStamp);
    strftime(buffer,80,"%Y-%m-%d %H:%M:%S",timeinfo);
    printf("%s\n",buffer);
    return string(buffer);
}

int main(void)
{
    convertTimeStamp2TimeStr(1633071600);  //2021-10-1 15:00:00
    return 0;
}
  • 时间字符串转时间戳(linux)
#include 
#include 
#include 
using namespace std;

time_t convertTimeStr2TimeStamp(string timeStr){
    struct tm timeinfo;
    strptime(timeStr.c_str(), "%Y-%m-%d %H:%M:%S",  &timeinfo);
    time_t timeStamp = mktime(&timeinfo);
    printf("timeStamp=%ld\n",timeStamp);
    return timeStamp;
}

int main(void)
{
    convertTimeStr2TimeStamp("2021-10-1 15:00:00");
    return 0;
}
  • 时间字符串转时间戳(windows)
//windows下没有strptime函数,可以使用scanf来格式化时间
#include 
#include 
#include 
#include 
using namespace std;

time_t StringToTimeStamp(string str){
    struct tm tm_;
    int year, month, day, hour, minute,second;
    sscanf(str.c_str(),"%d-%d-%d %d:%d:%d", &year, &month, &day, &hour, &minute, &second);
    tm_.tm_year  = year-1900;
    tm_.tm_mon   = month-1;
    tm_.tm_mday  = day;
    tm_.tm_hour  = hour;
    tm_.tm_min   = minute;
    tm_.tm_sec   = second;
    tm_.tm_isdst = 0;

    time_t timeStamp = mktime(&tm_);
    return timeStamp;
}

int main(void)
{
    cout << StringToTimeStamp("2021-10-1 15:00:00") << endl;
    return 0;
}
GetTickCount是一种函数。GetTickCount返回(retrieve)从操作系统启动所经过(elapsed)的毫秒数,它的返回值是DWORD。 ![在这里插入图片描述](https://img-blog.csdnimg.cn/322bccb752bb4cbc820aafc005409adc.png)

2、C++语言的时间函数

2.1 获取当前时间

#include 
#include 

int main()
{
    time_t now = time(nullptr);
    std::cout << "Now is: " << ctime(&now) << std::endl;
}
#include 
#include 
#include 

int main(){
    auto now = chrono::system_clock::now();
    time_t time = chrono::system_clock::to_time_t(now);
    std::cout << "Now is: " << ctime(&time) <<  std::endl;
    return 0;
}
time_t now = time(nullptr);
tm* t = localtime(&now);
cout << "Now is: " << t->tm_year + 1900 << "/" << t->tm_mon + 1<< "/" << t->tm_mday << " ";    cout << t->tm_hour << ":" << t->tm_min << ":" << t->tm_sec << endl; 

C++17新内容timespec,迈向纳秒精度。严格的C++的C-Style日期时间库,在C++17标准才正式引入timespec类型。

#include 
#include 
#include 

timespec ts;
timespec_get(&ts, TIME_UTC);
char buff[100];
strftime(buff, sizeof buff, "%D %T", std::gmtime(&ts.tv_sec));
printf("Current time: %s.%09ld UTC\n", buff, ts.tv_nsec);

【小沐学C++】C++17 实现日期和时间相关编程_第6张图片

2.2 计算时间差

  • 例子1:
#include 
#include 

using namespace std;

int main()
{
    time_t time1 = time(nullptr);
    double sum = 0;
    for(int i = 0; i < 1000000000; i++) {
        sum += sqrt(i);
    }
    time_t time2 = time(nullptr);

    double time_diff = difftime(time2, time1);
    cout << "time1: " << time1 << endl;
    cout << "time2: " << time2 << endl;
    cout << "time_diff: " << time_diff << "s" << endl;
}
  • 例子2:
#include 
#include 

using namespace std;

int main()
{
    auto start = chrono::steady_clock::now();
    double sum = 0;
    for(int i = 0; i < 100000000; i++) {
        sum += sqrt(i);
    }
    auto end = chrono::steady_clock::now();

    auto time_diff = end - start;
    auto duration = chrono::duration_cast<chrono::seconds>(time_diff);
    cout << "Operation cost : " << duration.count() << "s" << endl;
}
  • 例子3:
/*
 * This source file is part of FxSdk
 * @author 爱看书的小沐
 */

#ifndef FX_STOPWATCH_HEADER
#define FX_STOPWATCH_HEADER

#if defined(WIN32) || defined(WIN64)
#include 
#include 
#else
#include 
#endif

namespace FxLib { namespace System { 

///
// Simple Stopwatch class. Use this for high resolution timing 
// purposes (or, even low resolution timings)
// Pretty self-explanitory.... 
// Reset(), or GetElapsedSeconds().

class Timer
{
public:
	Timer(void)	// Constructor
	{
#if defined(WIN32) || defined(WIN64)
		QueryPerformanceFrequency(&m_CounterFrequency);
		QueryPerformanceCounter(&m_LastCount);
#else
		gettimeofday(&m_LastCount, 0);
#endif
	}

	// Resets timer (difference) to zero
	inline void Reset(void) 
	{
#if defined(WIN32) || defined(WIN64)
		QueryPerformanceCounter(&m_LastCount);
#else
		gettimeofday(&m_LastCount, 0);
#endif
	}					
	
	// Get elapsed time in seconds
	float GetElapsedSeconds(void)
	{
// Get the current count
#if defined(WIN32) || defined(WIN64)
		LARGE_INTEGER lCurrent;
		QueryPerformanceCounter(&lCurrent);

		return float((lCurrent.QuadPart - m_LastCount.QuadPart) /
								double(m_CounterFrequency.QuadPart));
#else
		timeval lcurrent;
		gettimeofday(&lcurrent, 0);
		float fSeconds = (float)(lcurrent.tv_sec - m_LastCount.tv_sec);
		float fFraction = (float)(lcurrent.tv_usec - m_LastCount.tv_usec) * 0.000001f;
		return fSeconds + fFraction;
#endif
	}	

	static float GetElapsedTime()
	{
		static LARGE_INTEGER previousTime;
		static LARGE_INTEGER freq;
		static bool init = false;
		if(!init){
			QueryPerformanceFrequency(&freq);
			QueryPerformanceCounter(&previousTime);
			init=true;
		}
		LARGE_INTEGER currentTime;
		QueryPerformanceCounter(&currentTime);
		unsigned long long elapsedTime = currentTime.QuadPart - previousTime.QuadPart;
		previousTime = currentTime;
		return (float)(elapsedTime)/(freq.QuadPart);
	}
	
	static void GetLocalTimeByCRT(char* timebuf, int nLen, const char pFormat[] = "%Y%m%d%H%M%S")
	{
		struct tm newtime;
		__time64_t long_time;
		errno_t err;

		// Get time as 64-bit integer.
		_time64( &long_time ); 
		// Convert to local time.
		err = _localtime64_s( &newtime, &long_time ); 
		if (err) {
			printf("Invalid argument to _localtime64_s.");
			return;
		}

/*
	 	struct tm   *newtime;
	 	time_t      szClock;
	 	// Get time in seconds
	 	time( &szClock );
	 	// Convert time to struct tm form
	 	newTime = localtime( &szClock );*/
		strftime( timebuf, nLen, pFormat, &newtime ); //"%Y%m%d%H%M%S"
	}

	static void GetLocalTimeByWIN(char* szBuf, int nLen, const char pFormat[] = "%Y%m%d%H%M%S")
	{
		SYSTEMTIME systime;
		::GetLocalTime(&systime);
		sprintf_s(szBuf, nLen, pFormat,
			systime.wYear, systime.wMonth, systime.wDay,
			systime.wHour, systime.wMinute, systime.wSecond); //"%u/%u/%u  %u:%u:%u"
	}

protected:
#if defined(WIN32) || defined(WIN64)
	LARGE_INTEGER m_CounterFrequency;
	LARGE_INTEGER m_LastCount;
#else
    timeval m_LastCount;
#endif
};

}} //namespace FxLib { namespace System { 
#endif //FX_STOPWATCH_HEADER

在C++11引入chrono库之前,C++程序员只能使用C-Style的日期时间库。然而,C-Style日期时间库有着鲜明的缺点:精度只有秒级别(当时),这对于对时间有着高精度要求的程序来说是完全不够用的。而C++11引入的chrono库解决了这个问题,它极大地扩展了对精度的支持。

2.3 UTC时间与本地时间

time_t now = time(nullptr);

tm* gm_time = gmtime(&now);
tm* local_time = localtime(&now);

cout << "gmtime: " << asctime(gm_time);
cout << "local_time: " << asctime(local_time);

2.4 chrono库

C++11的chrono库。主要包含了三种类型的时钟:
system_clock:来自系统范畴实时时钟的挂钟时间。
steady_clock:决不会调整的单调时钟。
high_resolution_clock:拥有可用的最短嘀嗒周期的时钟。

  • 计算一个时间间隔:
auto start = chrono::steady_clock::now();
double sum = 0;
for(int i = 0; i < 100000000; i++) {
    sum += sqrt(i);
}
auto end = chrono::steady_clock::now();

auto time_diff = end - start;
auto duration = chrono::duration_cast<chrono::milliseconds>(time_diff);
cout << "Operation cost : " << duration.count() << "ms" << endl;
  • 获取当前时间:
#include 
using namespace std;

int main()
{
    // 获取操作系统当前时间点(精确到微秒)
    chrono::time_point<chrono::system_clock, chrono::microseconds> tpMicro
        = chrono::time_point_cast<chrono::microseconds>(chrono::system_clock::now());
    // (微秒精度的)时间点 => (微秒精度的)时间戳
    time_t totalMicroSeconds = tpMicro.time_since_epoch().count();

    // (微秒精度的)时间戳 => (微秒精度的)时间间隔
    chrono::microseconds durMicro = chrono::microseconds(totalMicroSeconds);
    // (微秒精度的)时间间隔 => (微秒精度的)时间点
    tpMicro = chrono::time_point<chrono::system_clock, chrono::microseconds>(durMicro);
    // (各种精度的)时间点 => (秒精度的)时间戳
    time_t timestamp_s = std::chrono::system_clock::to_time_t(tpMicro);

    // 获取微秒时间
    int micro = (totalMicroSeconds % 1000000);

    // 将时间戳转换为时间格式
    tm time;
    gmtime_s(&time, &timestamp_s);

    char szTime[64];
    sprintf_s(szTime, "%04d-%02d-%02d %02d:%02d:%02d.%06d",
        time.tm_year + 1900, time.tm_mon + 1, time.tm_mday, (time.tm_hour + 8) % 24, time.tm_min, time.tm_sec, micro);
}

【小沐学C++】C++17 实现日期和时间相关编程_第7张图片

3、其他语言的时间函数

3.1 Java

  • Unix时间戳
time
  • Unix时间戳转time
String date = new java.text.SimpleDateFormat("dd/MM/yyyy HH:mm:ss").format(new java.util.Date(Unix timestamp * 1000))
  • time转Unix时间戳
long epoch = new java.text.SimpleDateFormat("dd/MM/yyyy HH:mm:ss").parse("01/01/1970 01:00:00");

3.2 JavaScript

  • Unix时间戳
Math.round(new Date().getTime()/1000)
getTime()返回数值的单位是毫秒
  • Unix时间戳转time
var unixTimestamp = new Date(Unix timestamp * 1000)
commonTime = unixTimestamp.toLocaleString()
  • time转Unix时间戳
var commonTime = new Date(Date.UTC(year, month - 1, day, hour, minute, second))

3.3 Microsoft .NET / C#

  • Unix时间戳
epoch = (DateTime.Now.ToUniversalTime().Ticks - 621355968000000000) / 10000000
  • Unix时间戳转time
public static DateTime _GetDateTime(long unixTime)
{
	return (new DateTime(1970, 1, 1)).AddSeconds(unixTime).ToLocalTime();
}
  • time转Unix时间戳
public static long _GetUnixTime(DateTime time)
{
	return (time.ToUniversalTime().Ticks / 10000000 - 62135596800);
}

3.4 MySQL

  • Unix时间戳
SELECT unix_timestamp(now())
  • Unix时间戳转time
from_unixtime(Unix timestamp)
  • time转Unix时间戳
SELECT unix_timestamp(time)
时间格式: YYYY-MM-DD HH:MM:SS 或 YYMMDD 或 YYYYMMDD

3.5 PHP

  • Unix时间戳
time()
  • Unix时间戳转time
date('r', Unix timestamp)
  • time转Unix时间戳
mktime(hour, minute, second, month, day, year)

3.6 PostgreSQL

  • Unix时间戳
SELECT extract(epoch FROM now())
  • Unix时间戳转time
SELECT TIMESTAMP WITH TIME ZONE 'epoch' + Unix timestamp) * INTERVAL '1 second';
  • time转Unix时间戳
SELECT extract(epoch FROM date('YYYY-MM-DD HH:MM:SS'));

3.7 Python

  • Unix时间戳
import time
time.time()
  • Unix时间戳转time
import time
time.gmtime(Unix timestamp)
  • time转Unix时间戳
import time
int(time.mktime(time.strptime('YYYY-MM-DD HH:MM:SS', '%Y-%m-%d %H:%M:%S')))

3.8 Ruby

  • Unix时间戳
获取Unix时间戳:Time.now 或 Time.new
显示Unix时间戳:Time.now.to_i
  • Unix时间戳转time
Time.at(Unix timestamp)
  • time转Unix时间戳
Time.local(year, month, day, hour, minute, second)

3.9 SQL Server

  • Unix时间戳
SELECT DATEDIFF(s, '1970-01-01 00:00:00', GETUTCDATE())
  • Unix时间戳转time
DATEADD(s, Unix timestamp, '1970-01-01 00:00:00')
  • time转Unix时间戳
SELECT DATEDIFF(s, '1970-01-01 00:00:00', time)

3.10 VBScript / ASP

  • Unix时间戳
DateDiff("s", "01/01/1970 00:00:00", Now())
  • Unix时间戳转time
DateAdd("s", Unix timestamp, "01/01/1970 00:00:00")
  • time转Unix时间戳
DateDiff("s", "01/01/1970 00:00:00", time)

4、时间的课外知识点

4.1 四季

我国古代以立春(2月4日或5日)、立夏(5月5日或6日)、立秋(8月7日或8日)、立冬(11月7日或8日)作为四季的开始。

民间习惯上用农历月份来划分四季:正月到三月春季,四到六月是夏季,七到九月是秋季,十月到腊月是冬季。正月初一是春天的第一天,故又叫春节。

在气象部门,通常以公历3—5月为春季,6—8月为夏季,911月为秋季,12—2月为冬季,并且常常把1、4、7、10月作为冬、春、夏、秋四季的代表月份。

在现代天文学上,则以春分(3月20日或21日)、夏至(6月21日或22日)、秋分(9月22日或23日)和冬至(12月21日或22日)作为四季的开始。

4.2 十二时辰

古代将一昼夜分为十二时辰,即:子、丑、寅、卯、辰、巳、午、未、申、酉、戌、亥。每一时辰相当于现代的两个小时。古人根据中国十二生肖中的动物的出没时间来命名各个时辰。子时23~1点,丑时1~3点,寅时3~5点,卯时5~7点,辰时7~9点,巳时9~11点,午时11~13点,未时13~15点,申时15~17点,酉时17~19点,戌时19~21点,亥时21~23点。

【小沐学C++】C++17 实现日期和时间相关编程_第8张图片
在现代生活中,时间是通过“时分秒”来记录的,但是在中国古代的时间记录方法非常具有中国特色,那就是十二地支。根据十二生肖中的动物的出没时间来命名各个时辰:子(zǐ) 、丑(chǒu) 、寅(yín) 、卯(mǎo) 、辰(chén) 、巳(sì) 、午(wǔ) 、未(wèi)、申(shēn) 、酉(yǒu) 、戌(xū) 、亥(hài)。

【小沐学C++】C++17 实现日期和时间相关编程_第9张图片
【小沐学C++】C++17 实现日期和时间相关编程_第10张图片
【小沐学C++】C++17 实现日期和时间相关编程_第11张图片

4.3 二十四时区

地球是自西向东自转,东边比西边先看到太阳,东边的时间也比西边的早。东边时刻与西边时刻的差值不仅要以时计,而且还要以分和秒来计算,这给人们带来不便。

为了克服时间上的混乱,1884年在华盛顿召开的一次国际经度会议(又称国际子午线会议)上,规定将全球划分为24个时区(东、西各12个时区)。规定英国(格林尼治天文台旧址)为中时区(零时区)、东1—12区,西1—12区。每个时区横跨经度15度,时间正好是1小时。最后的东、西第12区各跨经度7.5度,以东、西经180度为界。每个时区的中央经线上的时间就是这个时区内统一采用的时间,称为区时,相邻两个时区的时间相差1小时。

现今全球共分为24个时区。实际上,常常1个国家或1个省份同时跨着2个或更多时区,为了照顾到行政上的方便,常将1个国家或1个省份划在一起。所以时区并不严格按南北直线来划分,而是按自然条件来划分。例如,中国幅员宽广,差不多跨5个时区,但为了使用方便简单,实际上在只用东八时区的标准时即北京时间为准。

例如,中国东8区的时间总比泰国东7区的时间早1小时,而比日本东9区的时间晚1小时。因此,出国旅行的人,必须随时调整自己的手表,才能和当地时间相一致。凡向西走,每过一个时区,就要把表拨慢1小时(比如2点拨到1点);凡向东走,每过一个时区,就要把表拨快1小时(比如1点拨到2点)。并且规定英国(格林尼治天文台旧址)为本初子午线,即零度经线。



【小沐学C++】C++17 实现日期和时间相关编程_第12张图片

结语

如果您觉得该方法或代码有一点点用处,可以给作者点个赞,或打赏杯咖啡;╮( ̄▽ ̄)╭
如果您感觉方法或代码不咋地//(ㄒoㄒ)//,就在评论处留言,作者继续改进;o_O???
如果您需要相关功能的代码定制化开发,可以留言私信作者;(✿◡‿◡)
感谢各位大佬童鞋们的支持!( ´ ▽´ )ノ ( ´ ▽´)っ!!!

在这里插入图片描述

你可能感兴趣的:(C/C++,c++,utc,time,chrono,时间日期)