C++软件开发中“时间”相关操作全攻略
2017-11-01 00:04
411 查看
1. 时间概念
在日常生活中我们遇到的和时间相关的概念有北京时间、时差、12小时制、24小时制等,在软件开发中我们也经常遇到和时间相关的概念,软件虽说是一个虚拟的事物,但它仍然是来源于生活,不会脱离生活。我们在开发中遇到的时间概念大多可以对应上日常生活中的时间概念,但也有一些是软件作者(如微软等)人为制造的一些概念,如系统时间、文件时间等。格林威治时间(UTC Time)
本初子午线被定义为通过格林威治经线的位置,经过本初子午线的时间便被称为格林威治时间,相对这条经线的时区向东递增,向西递减,每隔一个时区,相差一个小时。
本地时间(LocalTime)
本地时间就是系统设置时区的当前时间,比如说当前系统设置的时区为“(UTC+08:00)北京,重庆,香港特别行政区,乌鲁木齐”(东八区),系统的右下角通知区域显示的时间为“2017/09/05 16:57”,那么这个时间就是当前系统的本地时间。
系统时间(SystemTime)
Windows的系统时间是就是格林威治时间(UTC时间)。
文件时间( FileTime )
Windows的文件时间为一个64位整数(用FILETIME结构体存储),可以理解为时间戳,只是这个时间戳比较特别,它记录从1601-1-1 00:00:00到当前格林威治时间(UTC)所经过的100纳秒(ns)数。注意,将这个数据转换为秒的话要除以10^7(1秒 = 10^9纳秒,这里是100纳秒单位)。
时间戳(Timestamp)
一个长整型整数,一般指从1970-01-01 00:00:00到当前格林威治时间(UTC)所经过的秒数,也有的指所经过的毫秒数。可以从站长之家查看。
2. 如何获取时间
CRT(C RunTime Library)、Windows API、Linux API都提供了获取时间的函数,常用的和时间相关的API有:time_t time(time_t * _Time); // 从1970-01-01 00:00:00到当前格林威治时间(UTC)所经过的秒数 errno_t gmtime_s(struct tm * _Tm, const time_t * _Time); errno_t localtime_s(struct tm * _Tm, const time_t * _Time); VOID GetSystemTime(LPSYSTEMTIME lpSystemTime); VOID GetLocalTime(LPSYSTEMTIME lpSystemTime); BOOL GetFileTime(HANDLE hFile, LPFILETIME lpCreationTime, LPFILETIME lpLastAccessTime, LPFILETIME lpLastWriteTime); BOOL LocalFileTimeToFileTime(CONST FILETIME *lpLocalFileTime, LPFILETIME lpFileTime); VOID GetSystemTimeAsFileTime(LPFILETIME lpSystemTimeAsFileTime); BOOL SystemTimeToTzSpecificLocalTime(CONST TIME_ZONE_INFORMATION *lpTimeZoneInformation, CONST SYSTEMTIME *lpUniversalTime, LPSYSTEMTIME lpLocalTime); BOOL TzSpecificLocalTimeToSystemTime(CONST TIME_ZONE_INFORMATION *lpTimeZoneInformation, CONST SYSTEMTIME *lpLocalTime, LPSYSTEMTIME lpUniversalTime); BOOL FileTimeToSystemTime(CONST FILETIME *lpFileTime, LPSYSTEMTIME lpSystemTime);
Win32 API中常出现FileTime,SystemTime就是第1节中说到的文件时间、系统时间。理解了时间概念之后,大部分时间操作就可以通过上面的API完成,下面列举一些常用的时间获取和转换的方法。
2.1 获取当前格林威治时间(UTC)
CRT API 精确到秒#include <time.h> time_t tUTC; time(&tUTC); struct tm tmUTC; gmtime_s(&tmUTC, &tUTC); printf("当前UTC时间: %04d-%02d-%02d %02d:%02d:%02d", tmUTC.tm_year + 1900, tmUTC.tm_mon + 1, tmUTC.tm_mday, tmUTC.tm_hour, tmUTC.tm_min, tmUTC.tm_sec);
Win32 API 精确到毫秒
#include <windows.h> SYSTEMTIME st; GetSystemTime(&st); printf("当前UTC时间: %04d-%02d-%02d %02d:%02d:%02d:%04d", st.wYear, st.wMonth, st.wDay, st.wHour, st.wMinute, st.wSecond, st.wMilliseconds);
2.2 获取当前本地时间
CRT API 精确到秒time_t tUTC; time(&tUTC); struct tm tmLocal; localtime_s(&tmLocal, &tUTC); // 根据系统时区设置来转换 printf("当前本地时间: %04d-%02d-%02d %02d:%02d:%02d", tmLocal.tm_year + 1900, tmLocal.tm_mon + 1, tmLocal.tm_mday, tmLocal.tm_hour, tmLocal.tm_min, tmLocal.tm_sec);
Win32 API 精确到毫秒
#include <windows.h> SYSTEMTIME st; GetLocalTime(&st); printf("当前本地时间: %04d-%02d-%02d %02d:%02d:%02d:%04d", st.wYear, st.wMonth, st.wDay, st.wHour, st.wMinute, st.wSecond, st.wMilliseconds);
2.3 获取Windows某个文件的文件时间
Win32 API#include <windows.h> HANDLE hFile = CreateFile(TEXT("E:\\test.txt"), GENERIC_READ, FILE_SHARE_READ|FILE_SHARE_WRITE, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); if(hFile != INVALID_HANDLE_VALUE) { FILETIME ftLastWriteTime; // 以文件最后写入时间为例 BOOL bRet = GetFileTime(hFile, NULL, NULL, &ftLastWriteTime); if(bRet) { ULARGE_INTEGER uli; uli.LowPart = ftLastWriteTime.dwLowDateTime; uli.HighPart = ftLastWriteTime.dwHighDateTime; printf("UTC文件上次写入时间戳: %llu\n", uli.QuadPart); SYSTEMTIME stUtcLastWrite; FileTimeToSystemTime(&ftLastWriteTime, &stUtcLastWrite); printf("UTC文件上次写入时间: %04d-%02d-%02d %02d:%02d:%02d:%04d\n", stUtcLastWrite.wYear, stUtcLastWrite.wMonth, stUtcLastWrite.wDay, stUtcLastWrite.wHour, stUtcLastWrite.wMinute, stUtcLastWrite.wSecond, stUtcLastWrite.wMilliseconds); } else { printf("获取文件时间失败\n"); } CloseHandle(hFile); hFile = INVALID_HANDLE_VALUE; }
2.4 获取时间戳(秒)
CRT API#include <time.h> time_t tUTC; // time_t为__int64类型 time(&tUTC); // tUTC中存储着从1970-01-01 00:00:00到当前格林威治时间(UTC)所经过的秒数
2.5 获取时间戳(微秒)
Win32 APIunion { long long ns100; FILETIME ft; } fileTime; GetSystemTimeAsFileTime(&fileTime.ft); // lNowMicroMS中存储着从1970-01-01 00:00:00到当前格林威治时间(UTC)所经过的微妙数 // 116444736000000000是从1601年1月1日00:00:00:000到1970年1月1日00:00:00:000所经过的100纳秒数 long long lNowMicroMS = (long long)((fileTime.ns100 - 116444736000000000LL) / 10LL);
Linux API
#include <sys/time.h> struct timeval tv; gettimeofday(&tv, NULL); // lNowMicroMS中存储着从1970-01-01 00:00:00到当前格林威治时间(UTC)所经过的微妙数 // long long lNowMicroMS = tv.tv_sec * 1000000 + tv.tv_usec;
3. 不同类型时间相互转化
3.1 UTC时间 转 本地时间
Win32 API#include <windows.h> SYSTEMTIME stUtc; // 构造UTC时间2017-09-05 15:24:55:120 stUtc.wYear = 2017; stUtc.wMonth = 9; stUtc.wDay = 5; stUtc.wHour = 15; stUtc.wMinute = 24; stUtc.wSecond = 55; stUtc.wMilliseconds = 120; SYSTEMTIME stLocal; SystemTimeToTzSpecificLocalTime(NULL, &stUtc, &stLocal); printf("本地时间: %04d-%02d-%02d %02d:%02d:%02d:%04d", stLocalLastWrite.wYear, stLocalLastWrite.wMonth, stLocalLastWrite.wDay, stLocalLastWrite.wHour, stLocalLastWrite.wMinute, stLocalLastWrite.wSecond, stLocalLastWrite.wMilliseconds);
3.2 本地时间 转 UTC时间
Win32 API#include <windows.h> SYSTEMTIME st; // 构造本地时间2017-09-05 23:24:55:120 st.wYear = 2017; st.wMonth = 9; st.wDay = 5; st.wHour = 23; st.wMinute = 24; st.wSecond = 55; st.wMilliseconds = 120; SYSTEMTIME stUtc; TzSpecificLocalTimeToSystemTime(NULL, &st, &stUtc); printf("UTC时间: %04d-%02d-%02d %02d:%02d:%02d:%04d", stUtc.wYear, stUtc.wMonth, stUtc.wDay, stUtc.wHour, stUtc.wMinute, stUtc.wSecond, stUtc.wMilliseconds);
3.3 时间戳(精确到秒) 转 UTC时间
CRT API#include <time.h> long timestamp = 1504622637; struct tm tmUTC; gmtime_s(&tmUTC, (time_t*)×tamp); printf("UTC时间: %04d-%02d-%02d %02d:%02d:%02d", tmUTC.tm_year + 1900, tmUTC.tm_mon + 1, tmUTC.tm_mday, tmUTC.tm_hour, tmUTC.tm_min, tmUTC.tm_sec);
3.4 时间戳(精确到微妙)转 UTC时间
Win32 APIlong long lTimestampMicroS = 1504677128644572; // 存储精确到微妙的时间戳 union { long long ns100; FILETIME ft; } fileTime; fileTime.ns100 = lTimestampMicroS * 10LL + 116444736000000000LL; SYSTEMTIME utcTime; FileTimeToSystemTime(&fileTime.ft, &utcTime); printf("UTC时间: %04d-%02d-%02d %02d:%02d:%02d:%04d", utcTime.wYear, utcTime.wMonth, utcTime.wDay, utcTime.wHour, utcTime.wMinute, utcTime.wSecond, utcTime.wMilliseconds);
3.5 UTC时间 转 时间戳(精确到秒)
CRT API// 将UTC 2017年11月12日 13:14:15转成时间戳 // struct tm tmUTC; tmUTC.tm_year = 2017 - 1900; // 减去1900 tmUTC.tm_mon = 11 - 1; // 减去1 tmUTC.tm_mday = 12; tmUTC.tm_hour = 13; tmUTC.tm_min = 14; tmUTC.tm_sec = 15; time_t timastampSec = mktime(&tmUTC);
相关文章推荐
- 软件开发时间操作全攻略
- 软件开发时间操作全攻略
- 软件开发时间操作全攻略
- c/c++时间操作相关函数
- Java软件开发基础知识梳理之(11)------Java中的GC操作及相关概念
- c++日期和时间相关操作-<time.h>(ctime)
- c++日期和时间相关操作-<time.h>(ctime)
- C/C++时间相关操作 SYSTEMTIME time_t 字符串的相互转换
- Microsoft Visual Studio 开发的C++程序软件发布相关事宜
- odoo开发笔记-日期时间相关操作
- C++软件开发相关知识笔记
- atitit.软件开发GUI 布局管理优缺点总结java swing wpf web html c++ qt php asp.net winform
- PHP 开发中数据库及其相关软件的选型考虑
- PHP 开发中数据库及其相关软件的选型考虑
- 【菜鸟玩Linux开发】在C++里操作MySQL
- Qt软件开发之sqlite数据库操作
- 流媒体行业需了解语言、常用软件、开发工具、相关协议及开发思想
- [工具分享]我常用的软件开发工具分享-for C++开发者
- 软件开发相关文档的写法
- 单链表相关操作的C++实现