zoukankan      html  css  js  c++  java
  • 输入日期显示星期几

    输入日期显示星期几

             比如今天是2013年8月2日,星期五。我们现在就是要实现这样一个功能,给定一个日期,得到该日期是星期几。

             比如:

    日期

    星期

    2013年8月2日

    星期五

    20130803

    星期六

    2013-08-04

    星期天

    2013-6-18

    星期二

    2014/1/16

    星期四

    2000/8/15

    星期二

             我们需要解决的问题有如下几点:

                      1.对输入格式进行归一化处理;

                       2.计算将来或以前某一天是星期几;

             一、对输入格式的归一化处理

             我们首先实现对输入格式的归一化处理,程序如下:

    // 输入日期的归一化处理
    #include <iostream>
    #include <string>
    using namespace std;
    
    struct date
    {
        int year;
        int month;
        int day;
    };
    
    int m_d[2][13] = { {0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31},
                       {0, 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31} };
    
    int is_leap(int year)
    {
        // 注意 year % 100 != 0
        //      year % 4   == 0
        //      year % 400 == 0
        // 这三者的顺序
        // 总共4中顺序组合,不同的顺序影响不同的计算效率
        if (year % 100 != 0 && year % 4 == 0 || year % 400 == 0)
        {
            return 1;
        }
        else
        {
            return 0;
        }
    }
    
    bool get_date(const string& str, date& dt)
    {
        dt.year = 0;
        dt.month = 0;
        dt.day = 0;
    
        int y(0), m(0), d(0);
        string sy, sm, sd;
        int f = 1;
        bool full = false, pass_d = false;
        for (string::size_type i = 0; i != str.size(); ++i)
        {
            // if (isdigit(static_cast<int>(str[i])))
            // 该语句导致isctype.c中断言错误:unsigned(c + 1) <= 256
            // 故改为:
            if (str[i] >= '0' && str[i] <= '9')
            {
                pass_d = false;
                if (f == 1)
                {
                    sy += str[i];
                    if (sy.size() == 4)
                    {
                        ++f;
                        full = true;
                    }
                }
                else if (f == 2)
                {
                    sm += str[i];
                    if (sm.size() == 2)
                    {
                        ++f;
                        full = true;
                    }
                }
                else if (f == 3)
                {
                    sd += str[i];
                    if (sd.size() == 2)
                    {
                        ++f;
                        full = true;
                    }
                }
                else if (f > 3)
                {
                    return false;
                }
            }
            else
            {
                if (pass_d == false)
                {
                    pass_d = true;
                    if (full == true)
                    {
                        full = false;
                    }
                    else
                    {
                        ++f;
                        /*if (f > 4)
                        {
                            return false;
                        }*/
                    }
                }
                else
                {
                    continue;
                }
            }
        }
    
        y = atoi(sy.c_str());
        m = atoi(sm.c_str());
        d = atoi(sd.c_str());
    
        if (m < 1 || m > 12)
        {
            return false;
        }
        else
        {
            if (d < 1 || d > m_d[is_leap(y)][m])
            {
                return false;
            }
        }
        dt.year = y;
        dt.month = m;
        dt.day = d;
        return true;
    }
    
    string uni_date(const date& dt)
    {
        string ret;
        char tmp[1000];
        
        itoa(dt.year, tmp, 10);
        ret += tmp;
        
        ret += '-';
        if (dt.month < 10)
        {
            ret += '0';
        }
        itoa(dt.month, tmp, 10);
        ret += tmp;
    
        ret += '-';
        if (dt.day < 10)
        {
            ret += '0';
        }
        itoa(dt.day, tmp, 10);
        ret += tmp;
    
        return ret;
    }
    
    int main()
    {
        string str;
        while (1)
        {
            cout << "输入:";
            cin >> str;
            date dt;
            cout << "输出:";
            if (get_date(str, dt))
            {
                cout << uni_date(dt) << endl;
            }
            else
            {
                cout << "输入日期非法!" << endl;
            }
            cout << endl;
        }
    }

             二、计算将来或以前某一天是星期几

             这里我们需要有个参照点,就以今天为参照点:20130802——星期五,我们首先计算将来某一天或以前某一天相对于今天相差几天,然后根据相差天数推算出具体是星期几。

             具体程序如下:

    // 计算将来或以前某一天是星期几
    #include <iostream>
    #include <string>
    using namespace std;
    
    struct date
    {
        int year;
        int month;
        int day;
    
        int weekday;
    
        static int m_d[2][13];
    
        static int y_d[2];
    
        static string d_w[8];
    };
    
    int date::m_d[2][13] = { {0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31},
                             {0, 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31} };
    
    int date::y_d[2] = {365, 366};
    
    string date::d_w[8] = {"", "星期一", "星期二", "星期三", "星期四", "星期五", "星期六", "星期天"};
    
    int is_leap(int year)
    {
        // 注意 year % 100 != 0
        //      year % 4   == 0
        //      year % 400 == 0
        // 这三者的顺序
        // 总共4中顺序组合,不同的顺序影响不同的计算效率
        if (year % 100 != 0 && year % 4 == 0 || year % 400 == 0)
        {
            return 1;
        }
        else
        {
            return 0;
        }
    }
    
    bool get_date(const string& str, date& dt)
    {
        dt.year = 0;
        dt.month = 0;
        dt.day = 0;
    
        int y(0), m(0), d(0);
        string sy, sm, sd;
        int f = 1;
        bool full = false, pass_d = false;
        for (string::size_type i = 0; i != str.size(); ++i)
        {
            // if (isdigit(static_cast<int>(str[i])))
            // 该语句导致isctype.c中断言错误:unsigned(c + 1) <= 256
            // 故改为:
            if (str[i] >= '0' && str[i] <= '9')
            {
                pass_d = false;
                if (f == 1)
                {
                    sy += str[i];
                    if (sy.size() == 4)
                    {
                        ++f;
                        full = true;
                    }
                }
                else if (f == 2)
                {
                    sm += str[i];
                    if (sm.size() == 2)
                    {
                        ++f;
                        full = true;
                    }
                }
                else if (f == 3)
                {
                    sd += str[i];
                    if (sd.size() == 2)
                    {
                        ++f;
                        full = true;
                    }
                }
                else if (f > 3)
                {
                    return false;
                }
            }
            else
            {
                if (pass_d == false)
                {
                    pass_d = true;
                    if (full == true)
                    {
                        full = false;
                    }
                    else
                    {
                        ++f;
                        /*if (f > 4)
                        {
                            return false;
                        }*/
                    }
                }
                else
                {
                    continue;
                }
            }
        }
    
        y = atoi(sy.c_str());
        m = atoi(sm.c_str());
        d = atoi(sd.c_str());
    
        if (m < 1 || m > 12)
        {
            return false;
        }
        else
        {
            if (d < 1 || d > date::m_d[is_leap(y)][m])
            {
                return false;
            }
        }
        dt.year = y;
        dt.month = m;
        dt.day = d;
        return true;
    }
    
    
    
    string uni_date(const date& dt)
    {
        string ret;
        char tmp[1000];
        
        itoa(dt.year, tmp, 10);
        ret += tmp;
        
        ret += '-';
        if (dt.month < 10)
        {
            ret += '0';
        }
        itoa(dt.month, tmp, 10);
        ret += tmp;
    
        ret += '-';
        if (dt.day < 10)
        {
            ret += '0';
        }
        itoa(dt.day, tmp, 10);
        ret += tmp;
    
        return ret;
    }
    
    string cal_weekday(date& dt)
    {
        string dt_str = uni_date(dt);
        string ref_str = "20130802";
        date ref_dt;
        ref_dt.year = 2013;
        ref_dt.month = 8;
        ref_dt.day = 2;
        ref_dt.weekday = 5;
    
        bool fut;
        date bigger, smaller;
        if (dt_str >= ref_str)
        {
            fut = true;
            bigger = dt;
            smaller = ref_dt;
        }
        else
        {
            fut = false;
            bigger = ref_dt;
            smaller = dt;
        }
        int smaller_days = 0, bigger_days = 0;
        for (int m = 1; m < smaller.month; ++m)
        {
            smaller_days += date::m_d[is_leap(smaller.year)][m];
        }
        smaller_days += smaller.day;
    
        for (int y = smaller.year; y < bigger.year; ++y)
        {
            bigger_days += date::y_d[is_leap(y)];
        }
        for (int m = 1; m < bigger.month; ++m)
        {
            bigger_days += date::m_d[is_leap(bigger.year)][m];
        }
        bigger_days += bigger.day;
    
        int diff = bigger_days - smaller_days;
        if (fut)
        {
            dt.weekday = (ref_dt.weekday + diff) % 7;
        }
        else
        {
            dt.weekday = ((ref_dt.weekday + 7) - (diff % 7)) % 7;
        }
        // 当为星期天时,dt.weekday为0,所以根据date::d_w[]需要做一下特殊处理
        if (dt.weekday == 0)
        {
            dt.weekday = 7;
        }
        return date::d_w[dt.weekday];
    }
    
    int main()
    {
        string str;
        while (1)
        {
            cout << "输入:";
            cin >> str;
            date dt;
            cout << "输出:";
            if (get_date(str, dt))
            {
                cout << uni_date(dt) << endl;
            }
            else
            {
                cout << "输入日期非法!" << endl << endl;
                continue;
            }
            cout << cal_weekday(dt) << endl;
            cout << endl;
        }
    }

             三、总结

             本文的初衷是想根据给定的日期得到其对应的星期。首先,我们对于输入的日期做了一个归一化处理,一是为了方便用户输入方便,二是为了我们后续处理的便捷。然后,我们对归一化处理后的日期进行计算,根据一个参照点(20130802——星期五)得到早于或晚于该天的星期。

  • 相关阅读:
    Call KernelIoControl in user space in WINCE6.0
    HOW TO:手工删除OCS在AD中的池和其他属性
    关于新版Windows Server 2003 Administration Tools Pack
    关于SQL2008更新一则
    微软发布3款SQL INJECTION攻击检测工具
    HyperV RTM!
    OCS 2007 聊天记录查看工具 OCSMessage
    CoreConfigurator 图形化的 Server Core 配置管理工具
    OC 2007 ADM 管理模板和Live Meeting 2007 ADM 管理模板发布
    Office Communications Server 2007 R2 即将发布
  • 原文地址:https://www.cnblogs.com/unixfy/p/3232969.html
Copyright © 2011-2022 走看看