summaryrefslogtreecommitdiff
path: root/tools/source/datetime/tdate.cxx
diff options
context:
space:
mode:
Diffstat (limited to 'tools/source/datetime/tdate.cxx')
-rw-r--r--tools/source/datetime/tdate.cxx540
1 files changed, 540 insertions, 0 deletions
diff --git a/tools/source/datetime/tdate.cxx b/tools/source/datetime/tdate.cxx
new file mode 100644
index 000000000000..72c188944096
--- /dev/null
+++ b/tools/source/datetime/tdate.cxx
@@ -0,0 +1,540 @@
+/*************************************************************************
+ *
+ * $RCSfile: tdate.cxx,v $
+ *
+ * $Revision: 1.1.1.1 $
+ *
+ * last change: $Author: hr $ $Date: 2000-09-18 17:03:06 $
+ *
+ * The Contents of this file are made available subject to the terms of
+ * either of the following licenses
+ *
+ * - GNU Lesser General Public License Version 2.1
+ * - Sun Industry Standards Source License Version 1.1
+ *
+ * Sun Microsystems Inc., October, 2000
+ *
+ * GNU Lesser General Public License Version 2.1
+ * =============================================
+ * Copyright 2000 by Sun Microsystems, Inc.
+ * 901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software Foundation.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ *
+ * Sun Industry Standards Source License Version 1.1
+ * =================================================
+ * The contents of this file are subject to the Sun Industry Standards
+ * Source License Version 1.1 (the "License"); You may not use this file
+ * except in compliance with the License. You may obtain a copy of the
+ * License at http://www.openoffice.org/license.html.
+ *
+ * Software provided under this License is provided on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ * See the License for the specific provisions governing your rights and
+ * obligations concerning the Software.
+ *
+ * The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ * Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ * All Rights Reserved.
+ *
+ * Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+
+#if defined( OS2 )
+#include <svpm.h>
+#elif defined( WNT )
+#include <svwin.h>
+#elif defined( WIN ) || defined( DOS )
+#include <dos.h>
+#elif defined( MAC )
+#include "mac_start.h"
+#ifndef __OSUTILS__
+#include "OSUtils.h"
+#endif
+#include "mac_end.h"
+#else
+#include <time.h>
+#endif
+
+#include <debug.hxx>
+#include <date.hxx>
+#ifdef MACOSX
+extern "C" {
+struct tm *localtime_r(const time_t *timep, struct tm *buffer);
+}
+#endif
+
+// =======================================================================
+
+static USHORT aDaysInMonth[12] = { 31, 28, 31, 30, 31, 30,
+ 31, 31, 30, 31, 30, 31 };
+
+#define MAX_DAYS 3636532
+
+// =======================================================================
+
+inline BOOL ImpIsLeapYear( USHORT nYear )
+{
+ return (((nYear % 4) == 0) && ((nYear % 100) != 0) || ((nYear % 400) == 0));
+}
+
+// -----------------------------------------------------------------------
+
+inline USHORT DaysInMonth( USHORT nMonth, USHORT nYear )
+{
+ if ( nMonth != 2 )
+ return aDaysInMonth[nMonth-1];
+ else
+ {
+ if ( ((nYear % 4) == 0) && ((nYear % 100) != 0) ||
+ ((nYear % 400) == 0) )
+ return aDaysInMonth[nMonth-1] + 1;
+ else
+ return aDaysInMonth[nMonth-1];
+ }
+}
+
+// -----------------------------------------------------------------------
+
+static long DateToDays( USHORT nDay, USHORT nMonth, USHORT nYear )
+{
+ long nDays;
+
+ nDays = ((ULONG)nYear-1) * 365;
+ nDays += ((nYear-1) / 4) - ((nYear-1) / 100) + ((nYear-1) / 400);
+ for( USHORT i = 1; i < nMonth; i++ )
+ nDays += DaysInMonth(i,nYear);
+ nDays += nDay;
+ return nDays;
+}
+
+// -----------------------------------------------------------------------
+
+static void DaysToDate( long nDays,
+ USHORT& rDay, USHORT& rMonth, USHORT& rYear )
+{
+ long nTempDays;
+ long i = 0;
+ BOOL bCalc;
+
+ do
+ {
+ nTempDays = (long)nDays;
+ rYear = (USHORT)((nTempDays / 365) - i);
+ nTempDays -= ((ULONG)rYear-1) * 365;
+ nTempDays -= ((rYear-1) / 4) - ((rYear-1) / 100) + ((rYear-1) / 400);
+ bCalc = FALSE;
+ if ( nTempDays < 1 )
+ {
+ i++;
+ bCalc = TRUE;
+ }
+ else
+ {
+ if ( nTempDays > 365 )
+ {
+ if ( (nTempDays != 366) || !ImpIsLeapYear( rYear ) )
+ {
+ i--;
+ bCalc = TRUE;
+ }
+ }
+ }
+ }
+ while ( bCalc );
+
+ rMonth = 1;
+ while ( (ULONG)nTempDays > DaysInMonth( rMonth, rYear ) )
+ {
+ nTempDays -= DaysInMonth( rMonth, rYear );
+ rMonth++;
+ }
+ rDay = (USHORT)nTempDays;
+}
+
+// =======================================================================
+
+Date::Date()
+{
+#if defined( OS2 )
+ DATETIME aDateTime;
+ DosGetDateTime( &aDateTime );
+
+ // Datum zusammenbauen
+ nDate = ((ULONG)aDateTime.day) +
+ (((ULONG)aDateTime.month)*100) +
+ (((ULONG)aDateTime.year)*10000);
+#elif defined( WNT )
+ SYSTEMTIME aDateTime;
+ GetLocalTime( &aDateTime );
+
+ // Datum zusammenbauen
+ nDate = ((ULONG)aDateTime.wDay) +
+ (((ULONG)aDateTime.wMonth)*100) +
+ (((ULONG)aDateTime.wYear)*10000);
+#elif ( defined( WIN ) || defined( DOS )) && !defined( BLC )
+ _dosdate_t aDate;
+ _dos_getdate( &aDate );
+
+ // Datum zusammenbauen
+ nDate = ((ULONG)aDate.day) +
+ (((ULONG)aDate.month)*100) +
+ (((ULONG)aDate.year)*10000);
+#elif ( defined( WIN ) || defined( DOS )) && defined( BLC )
+ dosdate_t aDate;
+ _dos_getdate( &aDate );
+
+ // Datum zusammenbauen
+ nDate = ((ULONG)aDate.day) +
+ (((ULONG)aDate.month)*100) +
+ (((ULONG)aDate.year)*10000);
+#elif defined( MAC )
+ DateTimeRec dt;
+ ::GetTime(&dt);
+ nDate = ((ULONG)dt.day) +
+ (((ULONG)dt.month)*100) +
+ (((ULONG)dt.year )*10000);
+#else
+ time_t nTmpTime;
+ struct tm aTime;
+
+ // Zeit ermitteln
+ nTmpTime = time( 0 );
+
+ // Datum zusammenbauen
+ if ( localtime_r( &nTmpTime, &aTime ) )
+ {
+ nDate = ((ULONG)aTime.tm_mday) +
+ (((ULONG)(aTime.tm_mon+1))*100) +
+ (((ULONG)(aTime.tm_year+1900))*10000);
+ }
+ else
+ nDate = 1 + 100 + (((ULONG)1900)*10000);
+#endif
+}
+
+// -----------------------------------------------------------------------
+
+void Date::SetDay( USHORT nNewDay )
+{
+ ULONG nMonth = GetMonth();
+ ULONG nYear = GetYear();
+
+ nDate = ((ULONG)(nNewDay%100)) + (nMonth*100) + (nYear*10000);
+}
+
+// -----------------------------------------------------------------------
+
+void Date::SetMonth( USHORT nNewMonth )
+{
+ ULONG nDay = GetDay();
+ ULONG nYear = GetYear();
+
+ nDate = nDay + (((ULONG)(nNewMonth%100))*100) + (nYear*10000);
+}
+
+// -----------------------------------------------------------------------
+
+void Date::SetYear( USHORT nNewYear )
+{
+ ULONG nDay = GetDay();
+ ULONG nMonth = GetMonth();
+
+ nDate = nDay + (nMonth*100) + (((ULONG)(nNewYear%10000))*10000);
+}
+
+// -----------------------------------------------------------------------
+
+DayOfWeek Date::GetDayOfWeek() const
+{
+ return (DayOfWeek)((ULONG)(DateToDays( GetDay(), GetMonth(), GetYear() )-1) % 7);
+}
+
+// -----------------------------------------------------------------------
+
+USHORT Date::GetDayOfYear() const
+{
+ USHORT nDay = GetDay();
+ for( USHORT i = 1; i < GetMonth(); i++ )
+ nDay += ::DaysInMonth( i, GetYear() );
+ return nDay;
+}
+
+// -----------------------------------------------------------------------
+
+USHORT Date::GetWeekOfYear( DayOfWeek eStartDay,
+ WeekCountStart eWeekStart ) const
+{
+ short nWeek;
+ short n1WDay = (short)Date( 1, 1, GetYear() ).GetDayOfWeek();
+ short nDayOfYear = (short)GetDayOfYear();
+
+ // Wochentage beginnen bei 0, deshalb einen abziehen
+ nDayOfYear--;
+ // StartDay beruecksichtigen
+ n1WDay = (n1WDay+(7-(short)eStartDay)) % 7;
+
+ if ( eWeekStart == WEEKCOUNT_FIRSTDAY )
+ {
+ nWeek = ((n1WDay+nDayOfYear)/7) + 1;
+ // 53te-Woche nur dann, wenn wir nicht schon in der ersten
+ // Woche des neuen Jahres liegen
+ if ( nWeek == 54 )
+ nWeek = 1;
+ else if ( nWeek == 53 )
+ {
+ short nDaysInYear = (short)GetDaysInYear();
+ short nDaysNextYear = (short)Date( 1, 1, GetYear()+1 ).GetDayOfWeek();
+ nDaysNextYear = (nDaysNextYear+(7-(short)eStartDay)) % 7;
+ if ( nDayOfYear > (nDaysInYear-nDaysNextYear-1) )
+ nWeek = 1;
+ }
+ }
+ else if ( eWeekStart == WEEKCOUNT_FIRSTFULLWEEK )
+ {
+ nWeek = ((n1WDay+nDayOfYear)/7);
+ // Erste Woche eines Jahres entspricht der letzen Woche des
+ // vorherigen Jahres
+ if ( nWeek == 0 )
+ {
+ Date aLastDatePrevYear( 31, 12, GetYear()-1 );
+ nWeek = aLastDatePrevYear.GetWeekOfYear( eStartDay, eWeekStart );
+ }
+ }
+ else // ( eWeekStart == WEEKCOUNT_FIRST4DAYWEEK )
+ {
+ // x_monday - thursday
+ if ( n1WDay < 4 )
+ nWeek = 1;
+ // friday
+ else if ( n1WDay == 4 )
+ nWeek = 53;
+ // saturday
+ else if ( n1WDay == 5 )
+ {
+ // Jahr nach Schaltjahr
+ if ( Date( 1, 1, GetYear()-1 ).IsLeapYear() )
+ nWeek = 53;
+ else
+ nWeek = 52;
+ }
+ // sunday
+ else
+ nWeek = 52;
+
+ if ( (nWeek == 1) || (nDayOfYear + n1WDay > 6) )
+ {
+ if ( nWeek == 1 )
+ nWeek += (nDayOfYear + n1WDay) / 7;
+ else
+ nWeek = (nDayOfYear + n1WDay) / 7;
+ if ( nWeek == 53 )
+ {
+ // naechster x_Sonntag == erster x_Sonntag im neuen Jahr
+ // == noch gleiche Woche
+ long nTempDays = DateToDays( GetDay(), GetMonth(), GetYear() );
+ nTempDays += 6 - (GetDayOfWeek()+(7-(short)eStartDay)) % 7;
+ USHORT nDay;
+ USHORT nMonth;
+ USHORT nYear;
+ DaysToDate( nTempDays, nDay, nMonth, nYear );
+ nWeek = Date( nDay, nMonth, nYear ).GetWeekOfYear( eStartDay, eWeekStart );
+ }
+ }
+ }
+
+ return (USHORT)nWeek;
+}
+
+// -----------------------------------------------------------------------
+
+USHORT Date::GetDaysInMonth() const
+{
+ return DaysInMonth( GetMonth(), GetYear() );
+}
+
+// -----------------------------------------------------------------------
+
+BOOL Date::IsLeapYear() const
+{
+ USHORT nYear = GetYear();
+ return ImpIsLeapYear( nYear );
+}
+
+// -----------------------------------------------------------------------
+
+BOOL Date::IsValid() const
+{
+ USHORT nDay = GetDay();
+ USHORT nMonth = GetMonth();
+ USHORT nYear = GetYear();
+
+ if ( !nMonth || (nMonth > 12) )
+ return FALSE;
+ if ( !nDay || (nDay > DaysInMonth( nMonth, nYear )) )
+ return FALSE;
+ else if ( nYear <= 1582 )
+ {
+ if ( nYear < 1582 )
+ return FALSE;
+ else if ( nMonth < 10 )
+ return FALSE;
+ else if ( (nMonth == 10) && (nDay < 15) )
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+// -----------------------------------------------------------------------
+
+Date& Date::operator +=( long nDays )
+{
+ USHORT nDay;
+ USHORT nMonth;
+ USHORT nYear;
+ long nTempDays = DateToDays( GetDay(), GetMonth(), GetYear() );
+
+ nTempDays += nDays;
+ if ( nTempDays > MAX_DAYS )
+ nDate = 31 + (12*100) + (((ULONG)9999)*10000);
+ else if ( nTempDays <= 0 )
+ nDate = 1 + 100;
+ else
+ {
+ DaysToDate( nTempDays, nDay, nMonth, nYear );
+ nDate = ((ULONG)nDay) + (((ULONG)nMonth)*100) + (((ULONG)nYear)*10000);
+ }
+
+ return *this;
+}
+
+// -----------------------------------------------------------------------
+
+Date& Date::operator -=( long nDays )
+{
+ USHORT nDay;
+ USHORT nMonth;
+ USHORT nYear;
+ long nTempDays = DateToDays( GetDay(), GetMonth(), GetYear() );
+
+ nTempDays -= nDays;
+ if ( nTempDays > MAX_DAYS )
+ nDate = 31 + (12*100) + (((ULONG)9999)*10000);
+ else if ( nTempDays <= 0 )
+ nDate = 1 + 100;
+ else
+ {
+ DaysToDate( nTempDays, nDay, nMonth, nYear );
+ nDate = ((ULONG)nDay) + (((ULONG)nMonth)*100) + (((ULONG)nYear)*10000);
+ }
+
+ return *this;
+}
+
+// -----------------------------------------------------------------------
+
+Date& Date::operator ++()
+{
+ USHORT nDay;
+ USHORT nMonth;
+ USHORT nYear;
+ long nTempDays = DateToDays( GetDay(), GetMonth(), GetYear() );
+
+ if ( nTempDays < MAX_DAYS )
+ {
+ nTempDays++;
+ DaysToDate( nTempDays, nDay, nMonth, nYear );
+ nDate = ((ULONG)nDay) + (((ULONG)nMonth)*100) + (((ULONG)nYear)*10000);
+ }
+
+ return *this;
+}
+
+// -----------------------------------------------------------------------
+
+Date& Date::operator --()
+{
+ USHORT nDay;
+ USHORT nMonth;
+ USHORT nYear;
+ long nTempDays = DateToDays( GetDay(), GetMonth(), GetYear() );
+
+ if ( nTempDays > 1 )
+ {
+ nTempDays--;
+ DaysToDate( nTempDays, nDay, nMonth, nYear );
+ nDate = ((ULONG)nDay) + (((ULONG)nMonth)*100) + (((ULONG)nYear)*10000);
+ }
+ return *this;
+}
+
+#ifndef MPW33
+
+// -----------------------------------------------------------------------
+
+Date Date::operator ++( int )
+{
+ Date aOldDate = *this;
+ Date::operator++();
+ return aOldDate;
+}
+
+// -----------------------------------------------------------------------
+
+Date Date::operator --( int )
+{
+ Date aOldDate = *this;
+ Date::operator--();
+ return aOldDate;
+}
+
+#endif
+
+// -----------------------------------------------------------------------
+
+Date operator +( const Date& rDate, long nDays )
+{
+ Date aDate( rDate );
+ aDate += nDays;
+ return aDate;
+}
+
+// -----------------------------------------------------------------------
+
+Date operator -( const Date& rDate, long nDays )
+{
+ Date aDate( rDate );
+ aDate -= nDays;
+ return aDate;
+}
+
+// -----------------------------------------------------------------------
+
+long operator -( const Date& rDate1, const Date& rDate2 )
+{
+ ULONG nTempDays1 = DateToDays( rDate1.GetDay(), rDate1.GetMonth(),
+ rDate1.GetYear() );
+ ULONG nTempDays2 = DateToDays( rDate2.GetDay(), rDate2.GetMonth(),
+ rDate2.GetYear() );
+ return nTempDays1 - nTempDays2;
+}