]> git.saurik.com Git - wxWidgets.git/blobdiff - src/common/datetime.cpp
partially working wxTaskBarIcon for X11
[wxWidgets.git] / src / common / datetime.cpp
index 11966062a4f116374aec1d5b0a59f13efa72668a..d796e6e12743cb498ad38cfd90c4ccc80993cfc4 100644 (file)
@@ -13,7 +13,7 @@
 //               so long as the above copyright and this permission statement
 //               are retained in all copies.
 //
-// Licence:     wxWindows license
+// Licence:     wxWindows licence
 ///////////////////////////////////////////////////////////////////////////////
 
 /*
     #undef HAVE_STRPTIME
 #endif // broken strptime()
 
+#if defined(__MWERKS__) && wxUSE_UNICODE
+    #include <wtime.h>
+#endif
+
 #if !defined(WX_TIMEZONE) && !defined(WX_GMTOFF_IN_TM)
     #if defined(__BORLANDC__) || defined(__MINGW32__) || defined(__VISAGECPP__)
         #define WX_TIMEZONE _timezone
     #elif defined(__MWERKS__)
         long wxmw_timezone = 28800;
         #define WX_TIMEZONE wxmw_timezone
-    #elif defined(__DJGPP__)
+    #elif defined(__DJGPP__) || defined(__WINE__)
         #include <sys/timeb.h>
         #include <values.h>
         static long wxGetTimeZone()
@@ -258,7 +262,8 @@ wxDateTime::wxDateTime_t GetNumOfDaysInMonth(int year, wxDateTime::Month month)
     return daysInMonth[wxDateTime::IsLeapYear(year)][month];
 }
 
-// ensure that the timezone variable is set by calling localtime
+// returns the time zone in the C sense, i.e. the difference UTC - local
+// (in seconds)
 static int GetTimeZone()
 {
     // set to TRUE when the timezone is set
@@ -266,20 +271,25 @@ static int GetTimeZone()
 #ifdef WX_GMTOFF_IN_TM
     static long gmtoffset = LONG_MAX; // invalid timezone
 #endif
-    
+
     wxCRIT_SECT_LOCKER(lock, gs_critsectTimezone);
 
+    // ensure that the timezone variable is set by calling localtime
     if ( !s_timezoneSet )
     {
         // just call localtime() instead of figuring out whether this system
         // supports tzset(), _tzset() or something else
-        time_t     t = 0;
+        time_t t = 0;
         struct tm *tm;
 
         tm = localtime(&t);
         s_timezoneSet = TRUE;
+
 #ifdef WX_GMTOFF_IN_TM
-        gmtoffset = tm->tm_gmtoff;
+        // note that GMT offset is the opposite of time zone and so to return
+        // consistent results in both WX_GMTOFF_IN_TM and !WX_GMTOFF_IN_TM
+        // cases we have to negate it
+        gmtoffset = -tm->tm_gmtoff;
 #endif
     }
 
@@ -1247,6 +1257,82 @@ wxDateTime& wxDateTime::ResetTime()
     return *this;
 }
 
+// ----------------------------------------------------------------------------
+// DOS Date and Time Format functions
+// ----------------------------------------------------------------------------
+// the dos date and time value is an unsigned 32 bit value in the format:
+// YYYYYYYMMMMDDDDDhhhhhmmmmmmsssss
+//
+// Y = year offset from 1980 (0-127)
+// M = month (1-12)
+// D = day of month (1-31)
+// h = hour (0-23)
+// m = minute (0-59)
+// s = bisecond (0-29) each bisecond indicates two seconds
+// ----------------------------------------------------------------------------
+
+wxDateTime& wxDateTime::SetFromDOS(unsigned long ddt)
+{
+    struct tm tm;
+
+    long year = ddt & 0xFE000000;
+    year >>= 25;
+    year += 80;
+    tm.tm_year = year;
+
+    long month = ddt & 0x1E00000;
+    month >>= 21;
+    month -= 1;
+    tm.tm_mon = month;
+
+    long day = ddt & 0x1F0000;
+    day >>= 16;
+    tm.tm_mday = day;
+
+    long hour = ddt & 0xF800;
+    hour >>= 11;
+    tm.tm_hour = hour;
+
+    long minute = ddt & 0x7E0;
+    minute >>= 5;
+    tm.tm_min = minute;
+
+    long second = ddt & 0x1F;
+    tm.tm_sec = second * 2;
+
+    return Set(mktime(&tm));
+}
+
+unsigned long wxDateTime::GetAsDOS() const
+{
+    unsigned long ddt;
+    time_t ticks = GetTicks();
+    struct tm *tm = localtime(&ticks);
+
+    long year = tm->tm_year;
+    year -= 80;
+    year <<= 25;
+
+    long month = tm->tm_mon;
+    month += 1;
+    month <<= 21;
+
+    long day = tm->tm_mday;
+    day <<= 16;
+
+    long hour = tm->tm_hour;
+    hour <<= 11;
+
+    long minute = tm->tm_min;
+    minute <<= 5;
+
+    long second = tm->tm_sec;
+    second /= 2;
+
+    ddt = year | month | day | hour | minute | second;
+    return ddt;
+}
+
 // ----------------------------------------------------------------------------
 // time_t <-> broken down time conversions
 // ----------------------------------------------------------------------------
@@ -1494,13 +1580,18 @@ wxDateTime& wxDateTime::Add(const wxDateSpan& diff)
 // Weekday and monthday stuff
 // ----------------------------------------------------------------------------
 
-bool wxDateTime::SetToTheWeek(wxDateTime_t numWeek, WeekDay weekday)
+bool wxDateTime::SetToTheWeek(wxDateTime_t numWeek,
+                              WeekDay weekday,
+                              WeekFlags flags)
 {
+    wxASSERT_MSG( numWeek > 0,
+                  _T("invalid week number: weeks are counted from 1") );
+
     int year = GetYear();
 
     // Jan 4 always lies in the 1st week of the year
     Set(4, Jan, year);
-    SetToWeekDayInSameWeek(weekday) += wxDateSpan::Weeks(numWeek);
+    SetToWeekDayInSameWeek(weekday, flags) += wxDateSpan::Weeks(numWeek - 1);
 
     if ( GetYear() != year )
     {
@@ -1523,17 +1614,34 @@ wxDateTime& wxDateTime::SetToLastMonthDay(Month month,
     return Set(GetNumOfDaysInMonth(year, month), month, year);
 }
 
-wxDateTime& wxDateTime::SetToWeekDayInSameWeek(WeekDay weekday)
+wxDateTime& wxDateTime::SetToWeekDayInSameWeek(WeekDay weekday, WeekFlags flags)
 {
     wxDATETIME_CHECK( weekday != Inv_WeekDay, _T("invalid weekday") );
 
-    WeekDay wdayThis = GetWeekDay();
+    int wdayThis = GetWeekDay();
     if ( weekday == wdayThis )
     {
         // nothing to do
         return *this;
     }
-    else if ( weekday < wdayThis )
+
+    if ( flags == Default_First )
+    {
+        flags = GetCountry() == USA ? Sunday_First : Monday_First;
+    }
+
+    // the logic below based on comparing weekday and wdayThis works if Sun (0)
+    // is the first day in the week, but breaks down for Monday_First case so
+    // we adjust the week days in this case
+    if( flags == Monday_First )
+    {
+        if ( wdayThis == Sun )
+            wdayThis += 7;
+    }
+    //else: Sunday_First, nothing to do
+
+    // go forward or back in time to the day we want
+    if ( weekday < wdayThis )
     {
         return Subtract(wxDateSpan::Days(wdayThis - weekday));
     }
@@ -2548,6 +2656,30 @@ const wxChar *wxDateTime::ParseFormat(const wxChar *date,
             width += *fmt - _T('0');
         }
 
+        // the default widths for the various fields
+        if ( !width )
+        {
+            switch ( *fmt )
+            {
+                case _T('Y'):               // year has 4 digits
+                    width = 4;
+                    break;
+
+                case _T('j'):               // day of year has 3 digits
+                case _T('l'):               // milliseconds have 3 digits
+                    width = 3;
+                    break;
+
+                case _T('w'):               // week day as number has only one
+                    width = 1;
+                    break;
+
+                default:
+                    // default for all other fields
+                    width = 2;
+            }
+        }
+
         // then the format itself
         switch ( *fmt )
         {
@@ -3109,7 +3241,7 @@ const wxChar *wxDateTime::ParseDate(const wxChar *date)
 
     // tokenize the string
     size_t nPosCur = 0;
-    static const wxChar *dateDelimiters = _T(".,/-\t\n ");
+    static const wxChar *dateDelimiters = _T(".,/-\t\r\n ");
     wxStringTokenizer tok(p, dateDelimiters);
     while ( tok.HasMoreTokens() )
     {