// ----------------------------------------------------------------------------
// FILE NAME: idate.hpp
//
// DESCRIPTION:
//   Declaration of the classes:
//     IDate
//
// COPYRIGHT:
//   IBM Open Class Library
//   Licensed Materials - Property of IBM
//
//   5645-001
//   (C) Copyright IBM Corporation 1992, 1997  All Rights Reserved.
//
// Revision: 95  1.6.1.4  source/core/base/idate.hpp, appsupport, ioc.v400, 980918  
// ----------------------------------------------------------------------------

#ifndef _IDATE_
#define _IDATE_

#include <istream.hpp>
#include <ibase.hpp>
#include <idatstrm.hpp>
#include <istring.hpp>

#if __IBMCPP__ >= 400
#pragma namemangling(compat)
#endif

// The "struct blocks" must be placed before SOM enablement test
#if (IC_OBSOLETE <= IC_OBSOLETE_2)





#endif

#pragma enum(4)
#pragma pack(push,4)

struct ICnrDate
{
  unsigned char  day;
  unsigned char  month;
  unsigned short year;
};


class IC_EXPORTB IDate
{
public:
    // ------------------------- Day/Month/Year Declarations -------------------
    typedef enum
    {
        Monday = 0,
        Tuesday,
        Wednesday,
        Thursday,
        Friday,
        Saturday,
        Sunday
    }   DayOfWeek;

    typedef enum 
    {
        January = 1,
        February,
        March,
        April,
        May,
        June,
        July,
        August,
        September,
        October,
        November,
        December
    }   Month;

    typedef enum
    {
        yy,
        yyyy
    }   YearFormat;

    // -------------------------- Constructors --------------------------------
                    IDate( );

                    IDate(Month aMonth, int aDay, int aYear);

                    IDate(int aDay, Month aMonth, int aYear);

                    IDate(int aYear, int aDay);

                    IDate(const IDate& aDate);

                    IDate(unsigned long julianDayNumber);

                    IDate(const ICnrDate& cnrDate);

    // ------------------------- Current Date ---------------------------------
    static IDate    today();

    // -------------------------- Diagnostics ---------------------------------
    IString asString(YearFormat yearFmt = yy) const;
    IString asString(const char *fmt) const;

    friend ostream& IC_EXPORTB operator<<(ostream& aStream, const IDate& aDate);

    // -------------------------- Day Queries ---------------------------------
    DayOfWeek       dayOfWeek() const;

    IString         dayName() const;

    int             dayOfMonth() const;
    int             dayOfYear() const;

    // -------------------------- Month Queries -------------------------------
    Month           monthOfYear() const;

    IString         monthName() const;

    // ------------------------- Year Queries ---------------------------------
    int             year() const;

    // ------------------------- Date Queries ---------------------------------
    unsigned long   julianDate() const;

    ICnrDate        asICnrDate() const;

    // -------------------------- Comparisons ---------------------------------
    bool            operator==(const IDate& aDate) const;
    bool            operator!=(const IDate& aDate) const;
    bool            operator<(const IDate& aDate) const;
    bool            operator<=(const IDate& aDate) const;
    bool            operator>(const IDate& aDate) const;
    bool            operator>=(const IDate& aDate) const;

    // ------------------------ Manipulations ---------------------------------
    IDate           operator+(int numDays) const;
    IDate           operator-(int numDays) const;

    IDate&          operator+=(int numDays);
    IDate&          operator-=(int numDays);

    long            operator-(const IDate& aDate) const;

    // ----------------------- General Date Queries ---------------------------
    static IString  dayName(DayOfWeek aDay);
    static IString  monthName(Month aMonth);

    static int      daysInMonth(Month aMonth, int aYear);
    static int      daysInYear(int aYear);

    // ------------------------- Validation -----------------------------------
    static bool     isLeapYear(int aYear);
    static bool     isValid(Month aMonth, int aDay, int aYear);
    static bool     isValid(int aDay, Month aMonth, int aYear);
    static bool     isValid(int aYear, int aDay);

    // ------------------------- Streaming ------------------------------------
    void            operator>>=(IDataStream &toWhere);
    void            operator<<=(IDataStream &fromWhere);

protected:
    // ------------------------- Initialize -----------------------------------
    IDate&          initialize(Month aMonth, int aDay, int aYear);

    // ------------------------- Streaming ------------------------------------
    void            writeToStream(IDataStream &toWhere) const;
    void            readFromStream(IDataStream &fromWhere);

private:
    // -------------------------------- Private -------------------------------
#if ( IC_OBSOLETE <= IC_OBSOLETE_2 )







#endif

    unsigned long   julian;
};

#pragma pack(pop)
#pragma enum(pop)

#if __IBMCPP__ >= 400
#pragma namemangling()
#endif

#include <idate.inl>

#endif
