软件开发时间操作全攻略
2017-09-06 15:52
316 查看
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代码示例
- 会员开通时间处理的存储过程|软件开发
- 利用简单的一元线性回归分析估计软件项目开发时间
- 程序开发中对时间的操作
- 更灵活的方式解决C语言开发中的时间操作问题
- 【web开发】☆★之利用POI操作Excel表格系列教程【4】设置时间单元格
- 软件项目的开发的时间视乎永远都不够用
- 时间去哪儿:软件的操作(时间去哪儿系列二)
- 【本周】软件开发中的时间管理—我的时间到哪里去了?
- 利用简单的一元线性回归分析估计软件项目开发时间
- jfreechart,pdf生成组件iText,jasper report报表组件及POI操作excel等在企业软件开发中常遇到的第三方应用
- Android软件开发之数据的操作详解
- odoo开发笔记-日期时间相关操作
- Android软件开发之获取通讯录联系人信息 + android联系人信息的存储结构 + Android联系人读取操作笔记
- 6 天时间修改 1 行代码:现实中的软件开发流程
- 实验:基本的系统安全控制 实验环境 某公司新增了一台企业级服务器,已安装运行RHEL 6操作系统,由系统运维部、软件开发部、技术服务部共同使用。由于用户数量众多,且使用时间不固定,要求针对账号和
- Android软件开发之获取通讯录联系人信息 + android联系人信息的存储结构 + Android联系人读取操作笔记