#pragma once
#ifndef __HWINDATETIME_H__
#define __HWINDATETIME_H__
#include <iostream>
#include <iomanip>
#include "hwinDef.h"
#include "hwinString.h"
#ifdef _MANAGED
#pragma managed(push,off)
#endif
#pragma pack(push,8)
namespace harlinn
{
namespace windows
{
namespace globalization
{
class Calendar;
};
class BinaryReader;
class BinaryWriter;
enum class DateTimeKind
{
Unspecified = 0,
Utc = 1,
Local = 2
};
enum class DayOfWeek
{
Sunday = 0,
Monday = 1,
Tuesday = 2,
Wednesday = 3,
Thursday = 4,
Friday = 5,
Saturday = 6
};
enum class DatePart
{
Year = 0,
DayOfYear = 1,
Month = 2,
Day = 3
};
class TimeBase
{
public:
static const long long TicksPerMillisecond = 10000;
static const long long TicksPerSecond = TicksPerMillisecond * 1000;
static const long long TicksPerMinute = TicksPerSecond * 60;
static const long long TicksPerHour = TicksPerMinute * 60;
static const long long TicksPerDay = TicksPerHour * 24;
HWIN_EXPORT static const double MillisecondsPerTick;
HWIN_EXPORT static const double SecondsPerTick;
HWIN_EXPORT static const double MinutesPerTick;
HWIN_EXPORT static const double HoursPerTick;
HWIN_EXPORT static const double DaysPerTick;
HWIN_EXPORT static const double OADateMinAsDouble;
HWIN_EXPORT static const double OADateMaxAsDouble;
HWIN_EXPORT static const int DaysToMonth365[13];
HWIN_EXPORT static const int DaysToMonth366[13];
static const int MillisPerSecond = 1000;
static const int MillisPerMinute = MillisPerSecond * 60;
static const int MillisPerHour = MillisPerMinute * 60;
static const int MillisPerDay = MillisPerHour * 24;
static const long long MaxSeconds = MaxInt64 / TicksPerSecond;
static const long long MinSeconds = MinInt64 / TicksPerSecond;
static const long long MaxMilliSeconds = MaxInt64 / TicksPerMillisecond;
static const long long MinMilliSeconds = MinInt64 / TicksPerMillisecond;
static const long long TicksPerTenthSecond = TicksPerMillisecond * 100;
static const long long UnixEpoch = 621355968000000000LL;
static const int DaysPerYear = 365;
static const int DaysPer4Years = DaysPerYear * 4 + 1;
static const int DaysPer100Years = DaysPer4Years * 25 - 1;
static const int DaysPer400Years = DaysPer100Years * 4 + 1;
static const int DaysTo1601 = DaysPer400Years * 4;
static const int DaysTo1899 = DaysPer400Years * 4 + DaysPer100Years * 3 - 367;
static const int DaysTo10000 = DaysPer400Years * 25 - 366;
static const long long MinTicks = 0;
static const long long MaxTicks = DaysTo10000 * TicksPerDay - 1;
static const long long MaxMillis = ( long long )DaysTo10000 * MillisPerDay;
static const long long FileTimeOffset = DaysTo1601 * TicksPerDay;
static const long long DoubleDateOffset = DaysTo1899 * TicksPerDay;
static const long long OADateMinAsTicks = ( DaysPer100Years - DaysPerYear ) * TicksPerDay;
};
class DateTime;
class TimeSpan : public TimeBase
{
friend class DateTime;
public:
HWIN_EXPORT static const TimeSpan Zero;
HWIN_EXPORT static const TimeSpan MaxValue;
HWIN_EXPORT static const TimeSpan MinValue;
private:
long long ticks;
HWIN_EXPORT static TimeSpan Interval( double theValue, int theScale );
public:
HWIN_EXPORT static long long TimeToTicks( int theDays, int theHours = 0, int theMinutes = 0, int theSeconds = 0, int theMilliseconds = 0 );
TimeSpan( )
: ticks( 0 )
{
}
explicit TimeSpan( long long theTicks )
: ticks( theTicks )
{
}
TimeSpan( const TimeSpan& other )
: ticks( other.ticks )
{
}
TimeSpan( int hours, int minutes, int seconds )
: ticks( TimeToTicks( 0, hours, minutes, seconds ) )
{
}
TimeSpan( int days, int hours, int minutes, int seconds )
: ticks( TimeToTicks( days, hours, minutes, seconds ) )
{
}
TimeSpan( int days, int hours, int minutes, int seconds, int milliseconds )
: ticks( TimeToTicks( days, hours, minutes, seconds, milliseconds ) )
{
}
size_t hash( ) const
{
return std::_Hash_seq( ( const unsigned char * )&ticks, sizeof( ticks ) );
}
long long Ticks( ) const
{
return ticks;
}
int Days( ) const
{
return ( int )( ticks / TicksPerDay );
}
int Hours( ) const
{
return ( int )( ( ticks / TicksPerHour ) % 24 );
}
int Milliseconds( ) const
{
return ( int )( ( ticks / TicksPerMillisecond ) % 1000 );
}
int Minutes( ) const
{
return ( int )( ( ticks / TicksPerMinute ) % 60 );
}
int Seconds( ) const
{
return ( int )( ( ticks / TicksPerSecond ) % 60 );
}
HWIN_EXPORT double TotalDays( ) const;
HWIN_EXPORT double TotalHours( ) const;
HWIN_EXPORT double TotalMilliseconds( ) const;
HWIN_EXPORT double TotalMinutes( ) const;
HWIN_EXPORT double TotalSeconds( ) const;
HWIN_EXPORT TimeSpan Add( const TimeSpan& other ) const;
static int Compare( const TimeSpan& t1, const TimeSpan& t2 )
{
if ( t1.ticks > t2.ticks )
{
return 1;
}
if ( t1.ticks < t2.ticks )
{
return -1;
}
return 0;
}
int CompareTo( const TimeSpan& value ) const
{
if ( ticks > value.ticks )
{
return 1;
}
if ( ticks < value.ticks )
{
return -1;
}
return 0;
}
static TimeSpan FromDays( double value )
{
return Interval( value, MillisPerDay );
}
HWIN_EXPORT TimeSpan Duration( ) const;
int HashCode( ) const
{
return ( int )ticks ^ ( int )( ticks >> 32 );
}
static TimeSpan FromHours( double value )
{
return Interval( value, MillisPerHour );
}
static TimeSpan FromMilliseconds( double value )
{
return Interval( value, 1 );
}
static TimeSpan FromMinutes( double value )
{
return Interval( value, MillisPerMinute );
}
HWIN_EXPORT TimeSpan Negate( ) const;
static TimeSpan FromSeconds( double value )
{
return Interval( value, MillisPerSecond );
}
HWIN_EXPORT TimeSpan Subtract( const TimeSpan& theOther ) const;
static TimeSpan FromTicks( long long value )
{
return TimeSpan( value );
}
TimeSpan operator + ( const TimeSpan& theValue ) const
{
return Add( theValue );
}
TimeSpan operator - ( const TimeSpan& theValue ) const
{
return Subtract( theValue );
}
template<typename T>
typename std::enable_if<std::is_arithmetic<T>::value, TimeSpan>::type operator * ( const T& theValue ) const
{
return TimeSpan( Ticks( ) * static_cast< long long >( theValue ) );
}
template<typename T>
friend typename std::enable_if<std::is_arithmetic<T>::value, TimeSpan>::type operator * ( const T& theValue, const TimeSpan& theTimeSpan )
{
return TimeSpan( static_cast< long long >( theValue )* theTimeSpan.Ticks( ) );
}
bool operator == ( const TimeSpan& other ) const
{
return CompareTo( other ) == 0;
}
bool operator != ( const TimeSpan& other ) const
{
return CompareTo( other ) != 0;
}
bool operator < ( const TimeSpan& other ) const
{
return CompareTo( other ) < 0;
}
bool operator <= ( const TimeSpan& other ) const
{
return CompareTo( other ) <= 0;
}
bool operator > ( const TimeSpan& other ) const
{
return CompareTo( other ) > 0;
}
bool operator >= ( const TimeSpan& other ) const
{
return CompareTo( other ) >= 0;
}
HWIN_EXPORT WideString ToString( ) const;
};
namespace globalization
{
class GregorianCalendar;
}
class DateTime : public TimeBase
{
public:
static const int KindShift = 62;
static const unsigned long long KindUnspecified = 0x0000000000000000;
static const unsigned long long KindUtc = 0x4000000000000000;
static const unsigned long long KindLocal = 0x8000000000000000;
static const unsigned long long TicksMask = 0x3FFFFFFFFFFFFFFF;
static const unsigned long long FlagsMask = KindUtc | KindLocal;
private:
friend class globalization::GregorianCalendar;
unsigned long long data;
HWIN_EXPORT explicit DateTime( unsigned long long dateData );
public:
HWIN_EXPORT static long long ToLocalTicks( long long ticksInUtc );
HWIN_EXPORT static long long ToUniversalTicks( long long ticksInLocalTime );
HWIN_EXPORT static long long ToTicks( int year, int month, int day, const globalization::Calendar& calendar );
HWIN_EXPORT static long long ToTicks( int year, int month, int day, int hour, int minute, int second, int millisecond );
HWIN_EXPORT static long long ToTicks( int year, int month, int day, int hour, int minute, int second, int millisecond, const globalization::Calendar& calendar );
HWIN_EXPORT static bool TryCreate( int year, int month, int day, int hour, int minute, int second, int millisecond, DateTime& result );
HWIN_EXPORT static const DateTime MinValue;
HWIN_EXPORT static const DateTime MaxValue;
HWIN_EXPORT static long long DateToTicks( int year, int month, int day );
HWIN_EXPORT static long long JulianDateToTicks( int year, int month, int day );
HWIN_EXPORT static long long TimeToTicks( int hour, int minute, int second );
HWIN_EXPORT static long long SystemTimeToTicks( const SYSTEMTIME& systemTime );
explicit DateTime( ) : data( 0 )
{
}
HWIN_EXPORT explicit DateTime( long long ticks );
HWIN_EXPORT explicit DateTime( double days );
HWIN_EXPORT DateTime( long long ticks, DateTimeKind kind );
HWIN_EXPORT DateTime( int year, int month, int day );
HWIN_EXPORT DateTime( int year, int month, int day, const globalization::Calendar& calendar );
HWIN_EXPORT DateTime( int year, int month, int day, int hour, int minute, int second );
HWIN_EXPORT DateTime( int year, int month, int day, int hour, int minute, int second, DateTimeKind kind );
HWIN_EXPORT DateTime( int year, int month, int day, int hour, int minute, int second, const globalization::Calendar& calendar );
HWIN_EXPORT DateTime( int year, int month, int day, int hour, int minute, int second, int millisecond );
HWIN_EXPORT DateTime( int year, int month, int day, int hour, int minute, int second, int millisecond, DateTimeKind kind );
HWIN_EXPORT DateTime( int year, int month, int day, int hour, int minute, int second, int millisecond, const globalization::Calendar& calendar );
HWIN_EXPORT DateTime( int year, int month, int day, int hour, int minute, int second, int millisecond, const globalization::Calendar& calendar, DateTimeKind kind );
size_t hash( ) const
{
return std::_Hash_seq( ( const unsigned char * )&data, sizeof( data ) );
}
long long Ticks( ) const
{
return data & TicksMask;
}
HWIN_EXPORT DateTime Add( const TimeSpan& value ) const;
HWIN_EXPORT DateTime Add( double value, int scale ) const;
HWIN_EXPORT DateTime AddDays( double value ) const;
HWIN_EXPORT DateTime AddHours( double value ) const;
HWIN_EXPORT DateTime AddMilliseconds( double value ) const;
HWIN_EXPORT DateTime AddMinutes( double value ) const;
HWIN_EXPORT DateTime AddMonths( int months ) const;
HWIN_EXPORT DateTime AddSeconds( double value ) const;
HWIN_EXPORT DateTime AddTicks( long long value ) const;
HWIN_EXPORT DateTime AddYears( int value ) const;
HWIN_EXPORT const DateTime& AssingTo( SYSTEMTIME& systemTime ) const;
HWIN_EXPORT AnsiString DateToAnsiString( ) const;
HWIN_EXPORT WideString DateToString( ) const;
HWIN_EXPORT AnsiString TimeToAnsiString( ) const;
HWIN_EXPORT WideString TimeToString( ) const;
HWIN_EXPORT AnsiString ToAnsiString( ) const;
HWIN_EXPORT WideString ToString( ) const;
HWIN_EXPORT TimeSpan Subtract( const DateTime& value ) const;
HWIN_EXPORT DateTime Subtract( const TimeSpan& value ) const;
HWIN_EXPORT static int Compare( const DateTime& t1, const DateTime& t2 );
HWIN_EXPORT int CompareTo( const DateTime& value ) const;
bool operator == ( const DateTime& other ) const
{
return CompareTo( other ) == 0;
}
bool operator != ( const DateTime& other ) const
{
return CompareTo( other ) != 0;
}
bool operator < ( const DateTime& other ) const
{
return CompareTo( other ) < 0;
}
bool operator <= ( const DateTime& other ) const
{
return CompareTo( other ) <= 0;
}
bool operator > ( const DateTime& other ) const
{
return CompareTo( other ) > 0;
}
bool operator >= ( const DateTime& other ) const
{
return CompareTo( other ) >= 0;
}
DateTime operator + ( const TimeSpan& theValue ) const
{
return Add( theValue );
}
DateTime operator - ( const TimeSpan& theValue ) const
{
return Subtract( theValue );
}
TimeSpan operator - ( const DateTime& theValue ) const
{
return Subtract( theValue );
}
HWIN_EXPORT static int DaysInMonth( int year, int month );
HWIN_EXPORT static long long DoubleDateToTicks( double value );
HWIN_EXPORT static DateTime FromBinary( long long dateData );
HWIN_EXPORT static DateTime FromFileTime( long long fileTime );
HWIN_EXPORT static DateTime FromFileTimeUtc( long long fileTime );
HWIN_EXPORT static DateTime FromOADate( double d );
HWIN_EXPORT bool IsDaylightSavingTime( ) const;
HWIN_EXPORT static DateTime SpecifyKind( const DateTime& value, DateTimeKind kind );
HWIN_EXPORT long long ToBinary( ) const;
HWIN_EXPORT int GetDatePart( DatePart datePart ) const;
HWIN_EXPORT void GetYearMonthDay( int& year, int& month, int& day ) const;
HWIN_EXPORT DateTime Date( ) const;
HWIN_EXPORT int Year( ) const;
HWIN_EXPORT int Month( ) const;
HWIN_EXPORT int Day( ) const;
HWIN_EXPORT DayOfWeek DayOfWeek( ) const;
HWIN_EXPORT int DayOfYear( ) const;
HWIN_EXPORT int Hour( ) const;
HWIN_EXPORT int Minute( ) const;
HWIN_EXPORT int Second( ) const;
HWIN_EXPORT int Millisecond( ) const;
HWIN_EXPORT TimeSpan TimeOfDay( ) const;
HWIN_EXPORT DateTimeKind Kind( ) const;
HWIN_EXPORT static DateTime Now( );
HWIN_EXPORT static DateTime UtcNow( );
HWIN_EXPORT static DateTime Today( );
HWIN_EXPORT static bool IsLeapYear( int year );
HWIN_EXPORT static double TicksToOADate( long long value );
HWIN_EXPORT double ToOADate( ) const;
HWIN_EXPORT long long ToFileTime( ) const;
HWIN_EXPORT long long ToFileTimeUtc( ) const;
HWIN_EXPORT DateTime ToLocalTime( ) const;
HWIN_EXPORT DateTime ToUniversalTime( ) const;
time_t ToTimeT( )
{
auto ticks = Ticks( );
return time_t( ticks != ( -0x7FFFFFFFFFFFFFFFL - 1L ) ? ( ticks - UnixEpoch ) / TimeSpan::TicksPerSecond : ( -0x7FFFFFFFFFFFFFFFL - 1L ) );
}
};
template<typename _Elem, typename _Traits >
std::basic_ostream< _Elem, _Traits > & operator << ( std::basic_ostream< _Elem, _Traits> & stream, const DateTime& time )
{
if ( time < DateTime::MinValue )
{
stream << "Invalid - less than 0001-01-01";
}
else if ( time > DateTime::MaxValue )
{
stream << "Invalid - greater than 9999-12-31";
}
else
{
int year, month, day;
time.GetYearMonthDay( year, month, day );
auto hours = time.Hour( );
auto minutes = time.Minute( );
auto seconds = time.Second( );
auto milliseconds = time.Millisecond( );
auto fill = stream.fill( );
auto width = stream.width( );
auto zero = stream.widen( '0' );
stream << std::setw( 4 ) << std::setfill( zero ) << year << '-'
<< std::setw( 2 ) << std::setfill( zero ) << month << '-'
<< std::setw( 2 ) << std::setfill( zero ) << day << ' '
<< std::setw( 2 ) << std::setfill( zero ) << hours << ':'
<< std::setw( 2 ) << std::setfill( zero ) << minutes << ':'
<< std::setw( 2 ) << std::setfill( zero ) << seconds << '.'
<< std::setw( 3 ) << std::setfill( zero ) << milliseconds << std::setw( width ) << std::setfill( fill );
}
return stream;
}
class Stopwatch
{
long long elapsedTicks;
long long startedAt;
bool isRunning;
static long long frequency;
public:
HWIN_EXPORT static const bool IsHighResolution;
private:
static double tickFrequency;
static bool InitializeStopwatch( );
long long GetElapsedDateTimeTicks( ) const;
public:
HWIN_EXPORT static long long GetTimestamp( );
HWIN_EXPORT static double GetTimestampInSeconds( );
HWIN_EXPORT static double GetTimestampInMilliseconds( );
HWIN_EXPORT static long long Frequency( );
HWIN_EXPORT Stopwatch( );
HWIN_EXPORT void Start( );
HWIN_EXPORT Stopwatch StartNew( );
HWIN_EXPORT void Stop( );
HWIN_EXPORT void Reset( );
HWIN_EXPORT void Restart( );
HWIN_EXPORT bool IsRunning( ) const;
HWIN_EXPORT TimeSpan Elapsed( ) const;
HWIN_EXPORT long long ElapsedMilliseconds( ) const;
HWIN_EXPORT long long ElapsedTicks( ) const;
};
}
}
namespace std
{
template<>
struct hash<harlinn::windows::TimeSpan>
{
size_t operator()( const harlinn::windows::TimeSpan& theValue ) const
{
return theValue.hash( );
}
};
template<>
struct hash<harlinn::windows::DateTime>
{
size_t operator()( const harlinn::windows::DateTime& theValue ) const
{
return theValue.hash( );
}
};
}
#pragma pack(pop)
#ifdef _MANAGED
#pragma managed(pop)
#endif
#endif