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——星期五)得到早于或晚于该天的星期。

  • 相关阅读:
    【POJ 2987 Firing】 最大权闭合子图
    【sgu176】有源汇有上下界的最大/最小流
    【HDU1263 水果】 STL之map应用经典好题
    【HDU1227 Fast Food】经典DP
    【hdu1043 && poj 1077】八数码问题
    有上下界的网络流问题
    【HDU4521】 dp思想+线段树操作
    miracl库下椭圆曲线方程常用函数使用入门
    函数指针
    python数据查询操作之 一场缺少db.commit()引发的血案……
  • 原文地址:https://www.cnblogs.com/unixfy/p/3232969.html
Copyright © 2011-2022 走看看