写出下面这段晦涩难懂但却极为高效的代码的人,真是个败类。

// For more information about Year 2038 problem please refer to
// http://en.wikipedia.org/wiki/Year_2038_problem
#include <iostream>
#include 
<ctime>
#include 
<cassert>
using namespace std;

class DateTime
{
public:    
    DateTime(
int year, int month, int day, int hour, int minute, int second)
    {    
        assert(year 
>= 1970 && year <= 2038);
        assert(month 
>= 1 && month <= 12);
        assert(day 
>= 1);
        assert(hour 
>= 0 && hour <= 23);
        assert(minute 
>= 0 && minute <= 59);
        assert(second 
>= 0 && second <= 59);

        
switch(month){
        
case 4:
        
case 6:
        
case 9:            
        
case 11:        
            assert(day 
<= 30);
            
break;
        
case 2:
            
if(year % 4 == 0)
                assert(day 
<= 29);
            
else
                assert(day 
<= 28);
            
break;        
        
default:
            assert(day 
<= 31);
        }

        
// 4 years
        timeStamp = secondsEvery4Years * ((year - 1970/ 4);
        
// year
        timeStamp += ((year - 1970% 4* secondsPerDay * 365;
        
// add one day if Feb 29 included
        if(((year - 1970% 4* 12 + month > 12 + 12 + 2// if contains a Feb 29 in the last 4-year-cycle
            timeStamp += secondsPerDay;
        
// month
        static const int daysInMonth[11= {3128313031303131303130};
        
for(; month > 1; month--)
            timeStamp 
+= daysInMonth[month - 2* secondsPerDay;
        
        
// day
        timeStamp += (day - 1* secondsPerDay;
        
// hour
        timeStamp += hour * secondsPerHour;
        
// minute
        timeStamp += minute * secondsPerMinute;
        
// second
        timeStamp += second;

        assert(timeStamp 
>= 0 && timeStamp <= 0x7fffffff);
    }
    
    
// overload constructor
    DateTime(time_t t)
    {
        assert(t 
>= 0 && t <= 0x7fffffff);
        timeStamp 
= t;
    }

    time_t GetTimeStamp()
    {
        
return timeStamp;
    }

    
int GetYear()
    {
        
int year = 1970 + (timeStamp / secondsEvery4Years) * 4;
        
int remain = timeStamp % secondsEvery4Years;
        
if(remain < 365 * 2 * secondsPerDay)
            year 
+= remain / (secondsPerDay * 365);
        
else if(remain < (365 * 2 + 366* secondsPerDay)
            year 
+= 2;
        
else
            year 
+= 3;
        
        
return year;
    }    

    
void GetDate(int* month, int* day)
    {
        assert(month 
!= NULL && day != NULL);
        
        
static const int sumNormal[13= {0315990120151181212243273304334365};
        
static const int sumLeapYear[13= {0316091121152182213244274305335366};
        
const int *sumDays = sumNormal;
        
int remain = timeStamp % secondsEvery4Years;

        
if(remain < secondsPerDay * (365 * 2 + 31 + 28))// 1st year 1-1 ~ 3rd year 2-28
            remain %= secondsPerDay * 365;
            
        
else if(remain < secondsPerDay * (365 * 3 + 1)){ // 3rd year 2-29 ~ 3rd year 12-31
            remain -= secondsPerDay * (365 * 2);
            sumDays 
= sumLeapYear; // has Feb 29
        }
        
else// 4th year 1-1 ~ 4th year 12-31
            remain -= secondsPerDay * (365 * 2 + 366);            

        
int idx = remain / (secondsPerDay * 29);
        
*month = remain >= sumDays[idx] * secondsPerDay ? idx + 1 : idx;                
        remain 
-= sumDays[*month - 1* secondsPerDay;
        
*day = remain / secondsPerDay + 1;
    }
        
    
// 0:Sunday, 1:Monday,  , 6:Saturday
    int GetDayOfWeek()
    {
        
return (timeStamp % secondsPerWeek / secondsPerDay + 4% 7;
    }

    
int GetHour()
    {
        
return timeStamp % secondsPerDay / secondsPerHour;
    }

    
int GetMinute()
    {
        
return timeStamp % secondsPerHour / secondsPerMinute;
    }

    
int GetSecond()
    {
        
return timeStamp % secondsPerMinute;
    }

    
virtual void Display()
    {
        
int month, day;
        
static const char* days[7= {"Sun""Mon""Tue""Wed""Tur""Fri""Sat"};
        GetDate(
&month, &day);
        cout
<< GetYear() << '-' << month << '-' << day << ' '
            
<< days[GetDayOfWeek()] << ' ' << GetHour() << ':' << GetMinute() << ':' << GetSecond() << endl;
    }
    
private:        
    time_t    timeStamp;
    
static const int secondsPerMinute = 60;
    
static const int secondsPerHour = secondsPerMinute * 60;
    
static const int secondsPerDay = secondsPerHour * 24;
    
static const int secondsPerWeek = secondsPerDay * 7;
    
static const int secondsEvery4Years = secondsPerDay * (365 * 3 + 366);    
};


// TimeFly is a class for testing DateTime
// It covers all the valid cases
class TimeFly
{
public:
    TimeFly():year(
1970), month(1), day(1), dayOfWeek(4), hour(0), minute(0), second(0), timeStamp(0)
    {}

    
virtual void Display()
    {
        
static const char* days[7= {"Sun""Mon""Tue""Wed""Tur""Fri""Sat"};
        cout
<< year << '-' << month << '-' << day << ' '
            
<< days[dayOfWeek] << ' ' << hour << ':' << minute << ':' << second << endl;
    }

    
bool DayChanges()
    {        
        dayOfWeek 
= ++dayOfWeek % 7;
        
static int daysInMonth[13= {0312831303130313130313031};// 1970 has no Feb29
        if(++day > daysInMonth[month]){
            day 
= 1;
            
if(++month > 12){
                month 
= 1;                
                daysInMonth[
2= ++year % 4 ? 28 : 29;
                cout 
<< year << endl;
            }
        }
        
return true;
    }

    
void HowTimeFlies()
    {
        
while(year != 2038 || day != 19 || minute != 14 || second != 7 || hour != 3){
            (second 
= ++second % 60|| (minute = ++minute % 60|| (hour = ++hour % 24|| DayChanges();
            timeStamp
++;

            DateTime dt 
= DateTime(year, month, day, hour, minute, second);            
            
int m, d;
            dt.GetDate(
&m, &d);            
            
if(dt.GetYear() != year || m != month || d != day || dt.GetDayOfWeek() != dayOfWeek || dt.GetHour() != hour || dt.GetMinute() != minute || dt.GetSecond() != second || dt.GetTimeStamp() != timeStamp){
                cout 
<< "TimeFly" << endl;
                Display();
                cout 
<< "DateTime" << endl;
                dt.Display();
            }            
        }
    }

private:
    
int second;
    
int minute;
    
int hour;
    
int dayOfWeek;
    
int day;
    
int month;
    
int year;
    
int timeStamp;
};

int main()
{                
    TimeFly fly;
    fly.HowTimeFlies();

    
return 0;
}

原谅我把上面的c++代码写得血肉模糊。因为C/C++如果不这么耍,就没意思了。

由于c#本身执行效率低,所以一定要注重表达,否则就真的没法混了。以下是逻辑明晰的c#代码,它完成了和上面c++编写的DateTime类一样的功能,而且完成得更出色,请看:

public static DateTime ParseUnixTimeStamp(int timeStamp)
{
    DateTime dt 
= new DateTime(197011000, DateTimeKind.Utc);
    
return dt.AddSeconds(timeStamp); ;
}

public static int GetUnixTimeStamp(DateTime dt) 
{
    DateTime dt1970 
= new DateTime(197011000, DateTimeKind.Utc);
    TimeSpan span 
= dt - dt1970;
    
return (int)(span.TotalSeconds);            
}
你是不是要说,C#真是个败类。
posted on 2009-02-26 10:28  MainTao  阅读(552)  评论(0编辑  收藏  举报