洞察探索open banking如何通过小程序容器技术助力金融企业实现数据安全和数字化转型
1082
2022-09-25
一个日期时间字符串的解析类
一个日期时间类,可以完成:
1. 从一个给定的日期时间字符串中解析出日期时间信息
2. 提供一些常用的日期时间的校验算法
该类支持的日期时间格式如下:
5(五秒)
4:5(四分五秒)
5:3:6(五时三分六秒)(注:不是五小时,而是凌晨五时,绝对时间)
2-28(2月28日)
2-28 5:3:6(2月28日)
2008-2-28(2008年2月28日)
2008-2-28 17:3:6(2008年2月28日17时3分6秒)
还支持站位符方式:
-2- 仅设定月份为2月,其余日期采用当前值
2008-- 仅设定年
:23: 仅设定分
-- :: 全部省略,采用当前日期时间作为默认值
如果不能解析到指定的部分,则采用默认值(默认值为当前日期)
头文件:
===================================================================
/*
类名:TDateTime
描述:日期时间类
作用:1. 从一个给定的日期时间字符串中解析出日期时间信息
2. 提供一些常用的日期时间的校验算法
备注:
该类支持的日期时间格式如下:
5(五秒)
4:5(四分五秒)
5:3:6(五时三分六秒)(注:不是五小时,而是凌晨五时,绝对时间)
2-28(2月28日)
2-28 5:3:6(2月28日)
2008-2-28(2008年2月28日)
2008-2-28 17:3:6(2008年2月28日17时3分6秒)
还支持站位符方式:
-2- 仅设定月份为2月,其余日期采用当前值
2008-- 仅设定年
:23: 仅设定分
-- :: 全部省略,采用当前日期时间作为默认值
如果不能解析到指定的部分,则采用默认值(默认值为当前日期)
历史:
2008-11-21 尹曙光([email]kevdmx@sina.com[/email]) 创建
*/
#ifndef _TDATETIME_H_20081121_
#define _TDATETIME_H_20081121_
//在windows下,如果强制使用32位的time_t,请定义以下宏:
//#ifndef _USE_32BIT_TIME_T
//#define _USE_32BIT_TIME_T
//#endif
#include
#ifndef BOOL
#define BOOL int
#endif
#ifndef TRUE
#define TRUE 1
#endif
#ifndef FALSE
#define FALSE 0
#endif
class TDateTime
{
public:
//年
unsigned short sYear;
//月
unsigned char sMonth;
//日
unsigned char sDay;
//时
unsigned char sHour;
//分
unsigned char sMinute;
//秒
unsigned char sSecond;
public:
//构造函数,采用当前的日期时间作为默认值
TDateTime();
//构造函数,从time_t类型的变量中取得日期时间
TDateTime(time_t t);
//从字符串中解析出日期时间,未解析到的部分,采用当前默认值
BOOL ParseDateTimeString(char *szDateTime);
//重新为当前的日期时间
BOOL LoadCurrentDateTime();
//转化为UNIX形式的time_t时间日期类型
time_t ToUnixDatetime();
//重新设定为有time_t类型变量指定的日期时间值
void FromUnixDatetime(time_t t);
//校验当前对象的日期时间数据是否正确
BOOL Validate();
//校验一个TDateTime类型变量的日期时间数据是否正确
static BOOL Validate(TDateTime *obDateTime);
//检查年份是否是闰年
static BOOL IsLeapYear(int year);
//校验给定的年份是否正确
static BOOL ValidateDate(int year);
//校验给定的年份和月分是否正确
static BOOL ValidateDate(int year,int month);
//取得给定的年份,给定的月份含有的天数
static int GetDaysOfMonth(int year, int month);
//校验给定的年月日数据是否正确
static BOOL ValidateDate(int year, int month, int day);
//检验给定的小时数据,是否正确
static BOOL ValidateTime(int hour);
//校验给定的小时分钟数据是否正确
static BOOL ValidateTime(int hour,int minute);
//校验给定的时间数据是否正确
static BOOL ValidateTime(int hour, int minute, int second);
//校验给定的日期时间数据是否正确
static BOOL ValidateDateTime(int year, int month, int day,
int hour, int minute, int second);
private:
//token类型定义
typedef enum TokenType
{
TT_Null = 0,
TT_Number =1,
TT_Minus = 2,
TT_Colon = 4,
TT_Blank = 8
};
//日期时间类型定义
typedef enum TimePart
{
TP_Second = 1,
TP_Minute = 2,
TP_Hour = 4,
TP_Day = 8,
TP_Month = 16,
TP_Year = 32
};
private:
//将当前对象变量清零
void ZeroDateTime(void);
//根据字符取得该字符所属的类型
TDateTime::TokenType GetTokenType(char c);
};
#endif //#ifndef _TDATETIME_H_20081121_
代码文件:
==================================================================
#include "stdafx.h"
#include
#include
#include "tdatetime.h"
//中国的时间区域为格林威治的东八区,故需要一个时间偏移量
const int TIMEZONE_8 = 8*60*60;
TDateTime::TDateTime()
{
LoadCurrentDateTime();
}
TDateTime::TDateTime(time_t t)
{
FromUnixDatetime(t);
}
TDateTime::TokenType
TDateTime::GetTokenType(char c)
{
if ((c>='0') && (c<='9'))
return TT_Number;
else if ('-'==c){
return TT_Minus;
}else if ('/'==c){
return TT_Minus;
}else if (' ' == c){
return TT_Blank;
}else if(':'==c){
return TT_Colon;
}else{
return TT_Null;
}
}
BOOL
TDateTime::ParseDateTimeString(char *szDateTime)
{
int len = strlen(szDateTime) - 1;
TimePart timePart = TP_Second;
int pw =1;//加权
signed short year=-1;
signed char month=-1,day=-1,hour=-1,minute=-1,second=-1;
//过滤尾部空格
while((len>=0) && (' ' == szDateTime[len]))
len--;
if (len<0) return FALSE;
while(len>=0){
char c = szDateTime[len];
switch( GetTokenType(c))
{
case TT_Null: goto ParseDateTimeString_FALSE;
case TT_Number:
switch(timePart)
{
case TP_Second:
if (second<0 )
second = c-'0';
else
second += (c-'0') * pw;
pw *= 10;
break;
case TP_Minute:
if (minute<0 )
minute = c-'0';
else
minute += (c-'0') * pw;
pw *= 10;
break;
case TP_Hour:
if (hour<0 )
hour = c-'0';
else
hour += (c-'0') * pw;
pw *= 10;
break;
case TP_Day:
if (day<0 )
day = c-'0';
else
day += (c-'0') * pw;
pw *= 10;
break;
case TP_Month:
if (month<0 )
month = c-'0';
else
month += (c-'0') * pw;
pw *= 10;
break;
case TP_Year:
if (year<0 )
year = c-'0';
else
year += (c-'0') * pw;
pw *= 10;
break;
default:
return FALSE;
}
break;
case TT_Minus:
switch(timePart)
{
case TP_Second: //如果没有给定时间信息,则跳过,直接升级到日期
pw =1;
timePart = TP_Month; //提升
day = second;
second = -1; //将解析到的秒信息改为日期信息
break;
case TP_Minute: goto ParseDateTimeString_FALSE;
case TP_Hour: goto ParseDateTimeString_FALSE;
case TP_Day:
pw =1;
timePart = TP_Month; //提升
break;
case TP_Month:
pw =1;
timePart = TP_Year; //提升
break;
case TP_Year: goto ParseDateTimeString_FALSE;
default: goto ParseDateTimeString_FALSE;
}
break;
case TT_Colon:
switch(timePart)
{
case TP_Second:
pw =1;
timePart = TP_Minute; //提升
break;
case TP_Minute:
pw =1;
timePart = TP_Hour; //提升
break;
case TP_Hour: goto ParseDateTimeString_FALSE;
case TP_Day: goto ParseDateTimeString_FALSE;
case TP_Month: goto ParseDateTimeString_FALSE;
case TP_Year: goto ParseDateTimeString_FALSE;
default: goto ParseDateTimeString_FALSE;
}
break;
case TT_Blank:
if (TP_Hour == timePart){
timePart = TP_Day; //提升
pw =1;
}else if (TP_Year == timePart){ //前导空格
goto ParseDateTimeString_OK;//认为结束
}else{//在其他部分不能出现空格
goto ParseDateTimeString_FALSE;
}
break;
}
len -- ;
}
ParseDateTimeString_OK:
if (year>0)
sYear = year;
if (month>0)
sMonth = month;
if (day>0)
sDay = day;
if (hour>=0)
sHour = hour;
if (minute>=0)
sMinute = minute;
if (second>=0)
sSecond = second;
if (Validate()){
return TRUE;
}else{
ZeroDateTime();
return FALSE;
}
ParseDateTimeString_FALSE:
ZeroDateTime();
return FALSE;
}
BOOL
TDateTime::LoadCurrentDateTime()
{
time_t t;
time(&t);
FromUnixDatetime(t);
return TRUE;
}
void
TDateTime::FromUnixDatetime(time_t t)
{
t += TIMEZONE_8;
struct tm *tt = gmtime( &t);
sYear = tt->tm_year+1900;
sMonth = tt->tm_mon+1;
sDay = tt->tm_mday;
sHour = tt->tm_hour;
sMinute = tt->tm_min;
sSecond = tt->tm_sec;
//free(tt);
}
void
TDateTime::ZeroDateTime(void)
{
sYear = 0;
sMonth = 0;
sDay = 0;
sHour = 0;
sMinute = 0;
sSecond = 0;
}
///
/// 判定给定的年份是否是润年
///
/// 需要判定的年份
///
BOOL
TDateTime::IsLeapYear(int year)
{
return ((year % 4 == 0) && (year % 100 != 0) || (year % 400 == 0));
}
///
/// 判定给定的年份是否有效。
///
/// 给定的年份
///
BOOL
TDateTime::ValidateDate(int year)
{
return (year > 0) && (year <= 9999);
}
///
/// 判定给定的年月是否有效
///
/// 给定的年份
/// 给定的月份
///
BOOL
TDateTime::ValidateDate(int year,int month)
{
if (!ValidateDate(year))
return FALSE;
return (month > 0) && (month < 13);
}
///
/// 得到一个月份的天数
///
/// 年
/// 月
///
int
TDateTime::GetDaysOfMonth(int year, int month)
{
if (!ValidateDate(year, month))
{
return 0;
}
if (month == 4 || month == 6 || month == 9 || month == 11)
{
return 30;
}
else if (month == 1 || month == 3 || month == 5
|| month == 7 || month == 8 || month == 10 || month == 12)
{
return 31;
}
else if (2 == month)
{
if (IsLeapYear(year))//如果是闰年
{
return 29;
}
else
{
return 28;
}
}
return 0;
}
///
/// 判定给定的年月日是否是一个有效的日期
///
/// 给定的年份
/// 给定的月份
/// 给定的日子
///
BOOL
TDateTime::ValidateDate(int year, int month, int day)
{
if (!ValidateDate(year, month))
return FALSE;
if ((day < 1) || (day > GetDaysOfMonth(year, month)))
return FALSE;
return TRUE;
}
///
/// 判定给定的小事是否有效
///
/// 给定的小时
///
BOOL
TDateTime::ValidateTime(int hour)
{
return (hour >= 0) && (hour < 24);
}
///
/// 判定给定的小时和分钟是否有效。
///
/// 给定的小时
/// 给定的分钟
///
BOOL
TDateTime::ValidateTime(int hour,int minute)
{
if (!ValidateTime(hour))
return FALSE;
return (minute >= 0) && (minute < 60);
}
///
/// 判定给定的小时、分钟、秒时否有效
///
/// 给定的小时
/// 给定的分钟
/// 给定的秒
///
BOOL
TDateTime::ValidateTime(int hour, int minute, int second)
{
if (!ValidateTime(hour,minute))
return FALSE;
return (second >= 0) && (second < 60);
}
///
/// 判定给定的年月日时分秒是否是一个有效的日期时间
///
/// 给定的年份
/// 给定的月份
/// 给定的日子
/// 给定的小时
/// 给定的分钟
/// 给定的秒
///
BOOL
TDateTime::ValidateDateTime(int year, int month, int day,
int hour, int minute, int second)
{
return ValidateDate(year, month, day)
&& ValidateTime(hour, minute, second);
}
BOOL
TDateTime::Validate()
{
return Validate(this);
}
BOOL
TDateTime::Validate(TDateTime *obDateTime)
{
return ValidateDateTime(obDateTime->sYear,obDateTime->sMonth, obDateTime->sDay,
obDateTime->sHour, obDateTime->sMinute, obDateTime->sSecond);
}
time_t
TDateTime::ToUnixDatetime()
{
tm tt;
tt.tm_year = sYear - 1900;
tt.tm_mon = sMonth -1;
tt.tm_mday = sDay;
tt.tm_hour = sHour;
tt.tm_min = sMinute;
tt.tm_sec = sSecond;
return mktime(&tt);
}
测试工程文件:
================================================================
// parsedt.cpp : 定义控制台应用程序的入口点。
//
#include "stdafx.h"
#include "tdatetime.h"
//注意:在给定参数时,日期和时间中间有空格分隔,故需要有引号限定
//如:exe "2008-11-21 22:23:59"
//在UNIX下可以使用“\”进行转义
//如:exe 2008-11-21\ 22:23:59
int main(int argc, char** argv)
{
TDateTime dtm;
if (argc<2){
printf("parsedt datetime_string");
return 1;
}
if (!dtm.ParseDateTimeString(argv[1])){
printf("Error!\n");
return 1;
}
printf("year:%d, month:%d, day:%d, hour:%d, minute:%d, second:%d\n",
dtm.sYear, dtm.sMonth, dtm.sDay, dtm.sHour, dtm.sMinute, dtm.sSecond);
TDateTime dtm2(dtm.ToUnixDatetime());
printf("year:%d, month:%d, day:%d, hour:%d, minute:%d, second:%d\n",
dtm2.sYear, dtm2.sMonth, dtm2.sDay, dtm2.sHour, dtm2.sMinute, dtm2.sSecond);
return 0;
}
VS2005下编译通过。该代码没有平台相关性,可以在UNIX下编译。
~~THE END~~
尹曙光
版权声明:本文内容由网络用户投稿,版权归原作者所有,本站不拥有其著作权,亦不承担相应法律责任。如果您发现本站中有涉嫌抄袭或描述失实的内容,请联系我们jiasou666@gmail.com 处理,核实后本网站将在24小时内删除侵权内容。
发表评论
暂时没有评论,来抢沙发吧~