一段实现日期显示的程序

我们都遇到过需要将整型时间按照一定格式显示的问题:如中文时间格式年-月-日 时:分:秒和英文时间格式MON/day Year hour:minute:second,或者是其它变化,如日期和时间不填0补齐和填0补齐等。

我们可以直接为每周时间输出格式准备一个输出函数,该输出函数基于format函数的格式来输出;但我们也需要一种通用的处理办法。

解决程序

该程序基于标准函数实现,包含如下的头文件:

#include <time.h>
#include <iostream>
#include <strstream>
#include <string>
using namespace std;

转换函数封装到一个类中(当然可以不封装);我们定义了枚举变量Field来限定处理字段为6(年、月、日、时、分、秒)的最多处理能力。

算法的第1步是分解格式字符串的信息:把格式串每个关键字段的格式及其后缀字符记录下来,并把各字段出现的先后顺序记录到nOrder变量中。

算法的第2步是把整型时间转换为tm结构,然后依据各字段出现的先后顺序,按照其记录的个数和后缀,拼成一个字符串。

class DateGen
{
public:
 //year, month, day, hour, minute, second
 enum{FIELDS=6};
 enum{YEAR, MONTH, DAY, HOUR, MINUTE, SECOND};
 //Format string as following:
 //YYYY-MM-DD hh:mm:ss
 //among which character like 'Y' is key word,
 //character like '-' is suffix.
 //Count of key words varys from 1 to 4 
 bool getDate(time_t nTime, const string& strFormat, string& strOutput)
 {
  static char* pszMonthName[] = {
   "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"
  };
  bool bRet = true;
  int nOrder[FIELDS];
  int index = -1; 
  m_nCurrField = -1;
  strOutput = "";
  for(int i = 0; i < strFormat.length(); i ++)
  {
   switch(strFormat[i])
   {
   case 'Y':modArray(index, YEAR, nOrder); break;    
   case 'M':modArray(index, MONTH, nOrder); break;
   case 'D':modArray(index, DAY, nOrder); break;
   case 'h':modArray(index, HOUR, nOrder); break;
   case 'm':modArray(index, MINUTE, nOrder);break;
   case 's':modArray(index, SECOND, nOrder); break;
   default:
    {
     if(index >= 0)
     {
      m_field[index].strSuffix += strFormat[i]; break;
     }
     else
     {
      bRet = false;
      //ignore
     }
     break;
    }
   }
  }
  struct tm* pTime =  localtime(&nTime);
  for(i = 0; i < FIELDS; i ++)
  {
   char szBuf[8];
   memset(szBuf, 0, sizeof(szBuf));
   int nVal = -1;
   switch(nOrder[i])
   {
   case YEAR:nVal = 1900 + pTime->tm_year; break;
   case MONTH:nVal = pTime->tm_mon + 1; break;
   case DAY:nVal = pTime->tm_mday; break;
   case HOUR:nVal = pTime->tm_hour; break;
   case MINUTE:nVal = pTime->tm_min; break;
   case SECOND:nVal = pTime->tm_sec; break;
   }
   if(MONTH == nOrder[i] && m_field[MONTH].nCount == 3)
   {
    strOutput += pszMonthName[nVal - 1];
   }
   else
   {
    ostrstream os(szBuf, sizeof(szBuf) - 1);
    os.width(m_field[nOrder[i]].nCount);
    os.fill('0');
    os << nVal;
    strOutput += os.str();
   }
   if(m_field[nOrder[i]].strSuffix.length() > 0)
   {
    strOutput += m_field[i].strSuffix;
   }   
  }
  
  return bRet;
 }
 void reset()
 {
  m_nCurrField = -1;
  for(int i = 0; i < FIELDS; i ++)
  {
   m_field[i].nCount = 0;
   m_field[i].strSuffix = "";
  }
 }
private:
 void modArray(int& index, const int nField, int nOrder[])
 {
  if(m_nCurrField != nField)
  {
   m_nCurrField = nField;
   index ++;    
   nOrder[index] = nField;
  }  
  m_field[m_nCurrField].nCount ++;
 }
 typedef struct Field
 {
  int nCount;
  string strSuffix;
  Field():nCount(0), strSuffix(""){};
 } Field;
 Field m_field[FIELDS];
 int m_nCurrField;
};

如下是一段使用代码,只是举例一下:

int main(int argc, char* argv[])
{
 DateGen gen;
 string strFormat = "YYYY-MM-DD hh::mm::ss";
 string strOutput;
 if(gen.getDate(time(NULL), strFormat, strOutput))
 {
  cout << "format:" << strFormat << endl;
  cout << strOutput << endl;
 }
 
 gen.reset();
 strFormat = "YYYY-MMM-DD hh::mm::ss"; 
 if(gen.getDate(time(NULL), strFormat, strOutput))
 {
  cout << "format:" << strFormat << endl;
  cout << strOutput << endl;
 }

 gen.reset();
 strFormat = "MM/DD/YYYY hh:mm:ss"; 
 if(gen.getDate(time(NULL), strFormat, strOutput))
 {
  cout << "format:" << strFormat << endl;
  cout << strOutput << endl;
 }
 return 0;
}

为了反复使用该类,特别加入了reset函数,把原来记录的信息复位。

这里只是提供了一种思路,在ascii环境下能够使用,并没有考虑unicode的情况。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值