[All OS] Module DateTime - Date as Double Since 1970

Share your advanced PureBasic knowledge/code with the community.
User avatar
mk-soft
Always Here
Always Here
Posts: 5335
Joined: Fri May 12, 2006 6:51 pm
Location: Germany

[All OS] Module DateTime - Date as Double Since 1970

Post by mk-soft »

Date as a double in seconds before or after the date "1970-01-01 00:00:00" as UTC.

MacOS supports the date as timeIntervalSince1970 as a double in seconds.

Windows supports the date as VariantTime as a double in days.
This can be converted well with an offset and factor, as well as conversion from and to SystemTime.

The features also include functions for get and set the CalendarGadget.

Update v1.02.0
- Added Linux

Update v1.03.0
- Change Linux to API (Date limits on x86 ca. 1902 to 2038)

Update v2.01.0
- Added: GetDateYear, GetDateMonth, etc

Update v2.02.1
- Added: GetDateFromValue(Year, ...)
- Change: GetDateNow remove parameter local.
- Change: GetStringFromDate parameter order. Local as last parameter.
- Change: GetDateFromString parameter order. Local as last parameter.
- Bugfix: Get/SetCalendarDate to valid local date.
- Fix: Calculation of date double at windows. Rounding error from windows to the result from macOS or Linux result.

Update v2.02.2
- Update Set/GetCalendarDate

Update v2.02.4
- Bugfix Linux SetCalendarDate

Update v2.03.1
- Added: FormatString with Milliseconds ("%hh:%ii:%ss.%nnn")
- Fix Linux: GetDateNow() with Milliseconds

Modul_DateTime.pb

Code: Select all

;-TOP

; Comment : Module DateTime, Date as Double UTC (Big Date Range)
; Author  : mk-soft
; Version : v2.03.1
; create  : 27.03.2021
; Update  : 19.11.2022
;
; OS      : Window, MacOS, Linux

; Link    : https://www.purebasic.fr/english/viewtopic.php?f=12&t=76983

; *******

DeclareModule DateTime
  
  Declare.s GetStringFromDate(Date.d, Mask.s = "%yyyy-%mm-%dd %hh:%ii:%ss", Local = #True)
  Declare.d GetDateFromString(Date.s, Mask.s = "%yyyy-%mm-%dd %hh:%ii:%ss", Local = #True)
  Declare.d GetDateFromValue(Year, Month, Day, Hour, Minute, Second, Local = #True)
  Declare.d GetDateNow()
  Declare   GetSecondsFromGMT()
  
  Declare   GetDateYear(Date.d, Local = #True)
  Declare   GetDateMonth(Date.d, Local = #True)
  Declare   GetDateDay(Date.d, Local = #True)
  Declare   GetDateHour(Date.d, Local = #True)
  Declare   GetDateMinute(Date.d, Local = #True)
  Declare   GetDateSecond(Date.d, Local = #True)
  Declare   GetDateDayOfWeek(Date.d, Local = #True)
      
  Declare.d GetCalendarDate(Gadget)
  Declare   SetCalendarDate(Gadget, Date.d)
  
EndDeclareModule

Module DateTime
  
  EnableExplicit
  
  CompilerSelect #PB_Compiler_OS
    CompilerCase #PB_OS_MacOS
      
      ;- OS MacOS
      
      ; Mask:
      ;   Year   = yyyy
      ;   Month  = MM (1..12), MMM (Short Name), MMMM (Long Name)
      ;   Day    = dd
      ;   Hour   = HH (0..23), hh (0..11); a = period (AM, PM)
      ;   Minute = mm
      ;   Second = ss
      ;   
      ;   Day ot the year   = DDD (1..3)
      ;   Week of Year      = ww
      ;   Week of Month     = W
      
      ; ----
      
      #kCFCalendarUnitEra = (1 << 1)
      #kCFCalendarUnitYear = (1 << 2) 
      #kCFCalendarUnitMonth = (1 << 3) 
      #kCFCalendarUnitDay = (1 << 4)
      #kCFCalendarUnitHour = (1 << 5)
      #kCFCalendarUnitMinute = (1 << 6)
      #kCFCalendarUnitSecond = (1 << 7)
      #kCFCalendarUnitWeek = (1 << 8)
      #kCFCalendarUnitWeekDay = (1 << 9)
      #kCFCalendarUnitWeekDayOrginal = (1 << 10)
      
      #NSCalendarUnitEra = #kCFCalendarUnitEra
      #NSCalendarUnitYear = #kCFCalendarUnitYear
      #NSCalendarUnitMonth = #kCFCalendarUnitMonth
      #NSCalendarUnitDay = #kCFCalendarUnitDay
      #NSCalendarUnitHour = #kCFCalendarUnitHour
      #NSCalendarUnitMinute = #kCFCalendarUnitMinute
      #NSCalendarUnitSecond = #kCFCalendarUnitSecond
      #NSCalendarUnitWeek = #kCFCalendarUnitWeek
      #NSCalendarUnitWeekDay = #kCFCalendarUnitWeekDay
      #NSCalendarUnitWeekDayOrdinal = #kCFCalendarUnitWeekDayOrginal
      
      ; -- Intern
      
      Macro CocoaString(NSString)
        PeekS(CocoaMessage(0, NSString, "UTF8String"), -1, #PB_UTF8)
      EndMacro
      
      ; ----
      
      Procedure GetDateComponent(Component, Date.d, Local = #True)
        Protected r1, NSPool, NSDate, NSDate2, NSCalendar, NSTimeZone, NSDateComponents
        
        NSPool = CocoaMessage(0, 0, "NSAutoreleasePool new")
        
        NSDate = CocoaMessage(0, 0, "NSDate new")
        NSDate2 = CocoaMessage(0, NSDate, "initWithTimeIntervalSince1970:@", @Date)
        
        NSCalendar = CocoaMessage(0, 0, "NSCalendar currentCalendar")
        If Not Local
          NSTimeZone = CocoaMessage(0, 0, "NSTimeZone timeZoneWithName:$", @"UTC")
          CocoaMessage(0, NSCalendar, "setTimeZone:", NSTimeZone)
        EndIf
        Select Component
          Case #PB_Date_Year
            NSDateComponents = CocoaMessage(0, NSCalendar, "components:", #NSCalendarUnitYear, "fromDate:", NSDate2)
            r1 = CocoaMessage(0, NSDateComponents, "year")
          Case #PB_Date_Month
            NSDateComponents = CocoaMessage(0, NSCalendar, "components:", #NSCalendarUnitMonth, "fromDate:", NSDate2)
            r1 = CocoaMessage(0, NSDateComponents, "month")
          Case #PB_Date_Day
            NSDateComponents = CocoaMessage(0, NSCalendar, "components:", #NSCalendarUnitDay, "fromDate:", NSDate2)
            r1 = CocoaMessage(0, NSDateComponents, "day")
          Case #PB_Date_Hour
            NSDateComponents = CocoaMessage(0, NSCalendar, "components:", #NSCalendarUnitHour, "fromDate:", NSDate2)
            r1 = CocoaMessage(0, NSDateComponents, "hour")
          Case #PB_Date_Minute
            NSDateComponents = CocoaMessage(0, NSCalendar, "components:", #NSCalendarUnitMinute, "fromDate:", NSDate2)
            r1 = CocoaMessage(0, NSDateComponents, "minute")
          Case #PB_Date_Second
            NSDateComponents = CocoaMessage(0, NSCalendar, "components:", #NSCalendarUnitSecond, "fromDate:", NSDate2)
            r1 = CocoaMessage(0, NSDateComponents, "second")
          Case #PB_Date_Week
            NSDateComponents = CocoaMessage(0, NSCalendar, "components:", #NSCalendarUnitWeekDay, "fromDate:", NSDate2)
            r1 = CocoaMessage(0, NSDateComponents, "weekday") - 1
        EndSelect
        
        CocoaMessage(0, NSPool, "release")
        
        ProcedureReturn r1
      EndProcedure
      
      ; ----
      
      ;-- Date functions
      
      Procedure.s GetStringFromDate(Date.d, Mask.s = "%yyyy-%mm-%dd %hh:%ii:%ss", Local = #True)
        Protected NSPool, NSDate, NSDate2, NSTimeZone, NSDateFormatter, NSString
        Protected r1.s
        
        NSPool = CocoaMessage(0, 0, "NSAutoreleasePool new")
        
        NSDateFormatter = CocoaMessage(0, 0, "NSDateFormatter new")
        ; Convert PB date format
        If Mask = ""
          Mask = "%yyyy-%mm-%dd %hh:%ii:%ss"
        EndIf
        If FindString(Mask, "%")
          mask = LCase(mask)
          mask = ReplaceString(mask, "m", "M")
          mask = ReplaceString(mask, "i", "m")
          mask = ReplaceString(mask, "h", "H")
          mask = ReplaceString(mask, "n", "S")
          mask = RemoveString(mask, "%")
        EndIf
        NSDate = CocoaMessage(0, 0, "NSDate new")
        NSDate2 = CocoaMessage(0, NSDate, "initWithTimeIntervalSince1970:@", @Date)
        If Not Local
          NSTimeZone = CocoaMessage(0, 0, "NSTimeZone timeZoneWithName:$", @"UTC")
          CocoaMessage(0, NSDateFormatter, "setTimeZone:", NSTimeZone)
        EndIf
        CocoaMessage(0, NSDateFormatter, "setDateFormat:$", @Mask)
        NSString = CocoaMessage(0, NSDateFormatter, "stringFromDate:@", @NSDate2)
        r1 = CocoaString(NSString)
        
        CocoaMessage(0, NSDateFormatter, "release")
        CocoaMessage(0, NSPool, "release")
        
        ProcedureReturn r1
      EndProcedure
      
      ; ----
      
      Procedure.d GetDateFromString(Date.s, Mask.s = "%yyyy-%mm-%dd %hh:%ii:%ss", Local = #True)
        Protected NSPool, NSDate, NSTimeZone, NSDateFormatter
        Protected r1.d
        
        NSPool = CocoaMessage(0, 0, "NSAutoreleasePool new")
        
        NSDateFormatter = CocoaMessage(0, 0, "NSDateFormatter new")
        ; Convert PB date format
        If Mask = ""
          Mask = "%yyyy-%mm-%dd %hh:%ii:%ss"
        EndIf
        If FindString(Mask, "%")
          mask = LCase(mask)
          mask = ReplaceString(mask, "m", "M")
          mask = ReplaceString(mask, "i", "m")
          mask = ReplaceString(mask, "h", "H")
          mask = ReplaceString(mask, "n", "S")
          mask = RemoveString(mask, "%")
        EndIf
        ; Date from string
        If Not Local
          NSTimeZone = CocoaMessage(0, 0, "NSTimeZone timeZoneWithName:$", @"UTC")
          CocoaMessage(0, NSDateFormatter, "setTimeZone:", NSTimeZone)
        EndIf
        CocoaMessage(0, NSDateFormatter, "setDateFormat:$", @Mask)
        NSDate = CocoaMessage(0, NSDateFormatter, "dateFromString:$", @Date)
        CocoaMessage(@r1, NSDate, "timeIntervalSince1970")
        CocoaMessage(0, NSDateFormatter, "release")
        
        CocoaMessage(0, NSPool, "release")
        
        ProcedureReturn r1
      EndProcedure
      
      ; -- Date function
      
      Procedure.d GetDateFromValue(Year, Month, Day, Hour, Minute, Second, Local = #True)
        Protected r1.d, NSPool, NSDate, NSCalendar, NSTimeZone, NSDateComponents
        
        NSPool = CocoaMessage(0, 0, "NSAutoreleasePool new")
        
        NSCalendar = CocoaMessage(0, 0, "NSCalendar currentCalendar")
        If Not Local
          NSTimeZone = CocoaMessage(0, 0, "NSTimeZone timeZoneWithName:$", @"UTC")
          CocoaMessage(0, NSCalendar, "setTimeZone:", NSTimeZone)
        EndIf
        
        NSDateComponents = CocoaMessage(0, 0, "NSDateComponents new")
        CocoaMessage(0, NSDateComponents, "setYear:", Year)
        CocoaMessage(0, NSDateComponents, "setMonth:", Month)
        CocoaMessage(0, NSDateComponents, "setDay:", Day)
        CocoaMessage(0, NSDateComponents, "setHour:", Hour)
        CocoaMessage(0, NSDateComponents, "setMinute:", Minute)
        CocoaMessage(0, NSDateComponents, "setSecond:", Second)
        NSDate = CocoaMessage(0, NSCalendar, "dateFromComponents:", NSDateComponents)
        CocoaMessage(@r1, NSDate, "timeIntervalSince1970")
        
        CocoaMessage(0, NSPool, "release")
        
        ProcedureReturn r1
      
      EndProcedure
      
      Procedure.d GetDateNow()
        Protected NSPool, NSDate
        Protected r1.d
        
        NSPool = CocoaMessage(0, 0, "NSAutoreleasePool new")
        NSDate = CocoaMessage(0, 0, "NSDate now")
        CocoaMessage(@r1, NSDate, "timeIntervalSince1970")
        CocoaMessage(0, NSPool, "release")
        ProcedureReturn r1
      EndProcedure
      
      ; ----
      
      Procedure GetSecondsFromGMT()
        Protected NSPool, NSTimeZone
        Protected r1
        
        NSPool = CocoaMessage(0, 0, "NSAutoreleasePool new")
        NSTimeZone = CocoaMessage(0, 0, "NSTimeZone localTimeZone")
        r1 = CocoaMessage(0, NSTimeZone, "secondsFromGMT")
        CocoaMessage(0, NSPool, "release")
        ProcedureReturn r1
      EndProcedure
      
      ;-- Calendar functions
      
      Procedure.d GetCalendarDate(Gadget)
        Protected NSPool, NSDate
        Protected r1.d
        
        NSPool = CocoaMessage(0, 0, "NSAutoreleasePool new")
        If GadgetType(Gadget) = #PB_GadgetType_Calendar
          NSDate = CocoaMessage(0, GadgetID(Gadget), "dateValue")
          CocoaMessage(@r1, NSDate, "timeIntervalSince1970")
        EndIf
        CocoaMessage(0, NSPool, "release")
        
        ProcedureReturn r1
      EndProcedure
      
      ; ----
      
      Procedure SetCalendarDate(Gadget, Date.d)
        Protected NSPool, NSDate, NSDate2
        
        NSPool = CocoaMessage(0, 0, "NSAutoreleasePool new")
        If GadgetType(Gadget) = #PB_GadgetType_Calendar
          NSDate = CocoaMessage(0, 0, "NSDate new")
          NSDate2 = CocoaMessage(0, NSDate, "initWithTimeIntervalSince1970:@", @Date)
          CocoaMessage(0, GadgetID(Gadget), "setDateValue:", NSDate2)
        EndIf  
        CocoaMessage(0, NSPool, "release")
        
      EndProcedure
      
      ; ----
      
    CompilerCase #PB_OS_Windows
      
      ;- OS Windows
      
      Import ""
        SystemTimeToTzSpecificLocalTime(lpTimeZoneInformation, lpUniversalTime, lpLocaleTime)
        TzSpecificLocalTimeToSystemTime(lpTimeZoneInformation, lpLocaleTime, lpUniversalTime)
      EndImport
      
      #DT_BASE_1970 = 25569.0
      
      ; -- Intern
      
      Procedure GetDateComponent(Component, Date.d, Local = #True)
        Protected r1, vTime.d 
        Static LastDate, Time.SystemTime
        
        If Date <> LastDate
          LastDate = Date
          ; Date to VariantTime
          vtime = (Date / 86400.0) + #DT_BASE_1970
          If Not VariantTimeToSystemTime_(vTime, @Time)
            ProcedureReturn -1
          EndIf
          ; UTC to Local
          If Local
            SystemTimeToTzSpecificLocalTime(0, Time, Time)
          EndIf
        EndIf
        Select Component
          Case #PB_Date_Year
            ProcedureReturn Time\wYear
          Case #PB_Date_Month
            ProcedureReturn Time\wMonth
          Case #PB_Date_Day
            ProcedureReturn Time\wDay
          Case #PB_Date_Hour
            ProcedureReturn Time\wHour
          Case #PB_Date_Minute
            ProcedureReturn Time\wMinute
          Case #PB_Date_Second
            ProcedureReturn Time\wSecond
          Case #PB_Date_Week
            ProcedureReturn Time\wDayOfWeek
        EndSelect
      EndProcedure
      
      ;-- Date functions
      
      Procedure.s GetStringFromDate(Date.d, Mask.s = "%yyyy-%mm-%dd %hh:%ii:%ss", Local = #True)
        Protected r1.s, cnt, vTime.d, Time.SystemTime, milliseconds.d
        
        milliseconds = date - Round(date, #PB_Round_Down)
        ; Date to VariantTime
        vtime = ((Date - milliseconds) / 86400.0) + #DT_BASE_1970
        If Not VariantTimeToSystemTime_(vTime, @Time)
          ProcedureReturn ""
        EndIf
        ; UTC to Local
        If Local
          SystemTimeToTzSpecificLocalTime(0, Time, Time)
        EndIf
        ; SystemTime to String
        If Mask = ""
          Mask = "%yyyy-%mm-%dd %hh:%ii:%ss"
        EndIf
        mask = LCase(mask)
        cnt = CountString(mask, "y")
        r1 = RemoveString(Mask, "%")
        If cnt = 2
          r1 = ReplaceString(r1, "yy", RSet(Str(Time\wYear % 100), 4, "0"))
        Else
          r1 = ReplaceString(r1, "yyyy", RSet(Str(Time\wYear), 4, "0"))
        EndIf
        r1 = ReplaceString(r1, "mm", RSet(Str(Time\wMonth), 2, "0"))
        r1 = ReplaceString(r1, "dd", RSet(Str(Time\wDay),2, "0"))
        r1 = ReplaceString(r1, "hh", RSet(Str(Time\wHour),2, "0"))
        r1 = ReplaceString(r1, "ii", RSet(Str(Time\wMinute),2, "0"))
        r1 = ReplaceString(r1, "ss", RSet(Str(Time\wSecond),2, "0"))
        r1 = ReplaceString(r1, "nnn", Right(StrD(milliseconds, 3), 3))
        ProcedureReturn r1
      EndProcedure
      
      ; ----
      
      Procedure.d GetDateFromString(Date.s, Mask.s = "%yyyy-%mm-%dd %hh:%ii:%ss", Local = #True)
        Protected r1.d, pos, cnt, vtime.d, Time.SystemTime, milliseconds.d
        
        ; String to SystemTime
        If Mask = ""
          Mask = "%yyyy-%mm-%dd %hh:%ii:%ss"
        EndIf
        mask = LCase(mask)
        mask = RemoveString(mask, "%")
        cnt = CountString(mask, "y")
        pos = FindString(mask, "y")
        If pos
          Time\wYear = Val(Mid(Date, pos, cnt))
        EndIf
        pos = FindString(mask, "m")
        If pos
          Time\wMonth = Val(Mid(Date, pos, 2))
        EndIf
        pos = FindString(Mask, "d")
        If pos
          Time\wDay = Val(Mid(Date, pos, 2))
        EndIf
        pos = FindString(Mask, "h")
        If pos
          Time\wHour = Val(Mid(Date, pos, 2))
        EndIf
        pos = FindString(Mask, "i")
        If pos
          Time\wMinute = Val(Mid(Date, pos, 2))
        EndIf
        pos = FindString(Mask, "s")
        If pos
          Time\wSecond = Val(Mid(Date, pos, 2))
        EndIf
        pos = FindString(Mask, "n")
        If pos
          milliseconds = ValD(Mid(Date, pos, 3))
        EndIf
        If Local
          TzSpecificLocalTimeToSystemTime(0, Time, Time)
        EndIf
        
        SystemTimeToVariantTime_(Time, @vTime)
        r1 = Round((vtime - #DT_BASE_1970) * 86400000.0 + milliseconds, #PB_Round_Nearest) * 0.001
        ProcedureReturn r1
      EndProcedure
      
      ; ----
      
      Procedure.d GetDateFromValue(Year, Month, Day, Hour, Minute, Second, Local = #True)
        Protected r1.d, vtime.d, Time.SystemTime
        
        Time\wYear = Year
        Time\wMonth = Month
        Time\wDay = Day
        Time\wHour = Hour
        Time\wMinute = Minute
        Time\wSecond = Second
        If Local
          TzSpecificLocalTimeToSystemTime(0, Time, Time)
        EndIf
        
        SystemTimeToVariantTime_(Time, @vTime)
        r1 = Round((vtime - #DT_BASE_1970) * 86400000.0 + Time\wMilliseconds, #PB_Round_Nearest) * 0.001
        ProcedureReturn r1
      EndProcedure
      
      ; ----
      
      Procedure.d GetDateNow()
        Protected r1.d, vTime.d, Time.SystemTime
        
        GetSystemTime_(@Time)
        SystemTimeToVariantTime_(Time, @vTime)
        r1 = Round((vtime - #DT_BASE_1970) * 86400000.0 + Time\wMilliseconds, #PB_Round_Nearest) * 0.001
        ProcedureReturn r1
      EndProcedure
      
      ; ----
      
      Procedure GetSecondsFromGMT()
        Protected r1.d, vTime.d, TimeZone.TIME_ZONE_INFORMATION
        
        GetTimeZoneInformation_(@TimeZone)
        With TimeZone
          r1 = (\Bias + \DaylightBias) * -60 
        EndWith
         
        ProcedureReturn r1
      EndProcedure
      
      
      ;-- Calendar functions
      
      Procedure.d GetCalendarDate(Gadget)
        Protected r1.d, vTime.d, Time.SystemTime
        SendMessage_(GadgetID(Gadget), #DTM_GETSYSTEMTIME, 0, Time)
        TzSpecificLocalTimeToSystemTime(0, Time, Time)
        SystemTimeToVariantTime_(Time, @vTime)
        r1 = (vtime - #DT_BASE_1970) * 86400.0
        ProcedureReturn r1
      EndProcedure
      
      ; ----
      
      Procedure SetCalendarDate(Gadget, Date.d)
        Protected vTime.d, Time.SystemTime
        ; Date to VariantTime
        vTime = (Date / 86400.0) + #DT_BASE_1970
        If Not VariantTimeToSystemTime_(vTime, @Time)
          ProcedureReturn 0
        EndIf
        SystemTimeToTzSpecificLocalTime(0, Time, Time)
        SendMessage_(GadgetID(Gadget), #DTM_SETSYSTEMTIME, #GDT_VALID, Time)
      EndProcedure
      
    CompilerCase #PB_OS_Linux
      
      ;- OS Linux
      
      CompilerIf #PB_Compiler_Processor = #PB_Processor_x86
        CompilerWarning "Linux Date Limit from 1901-12-14 to 2038-04-19"
      CompilerEndIf
      
      ; ----
      
      Structure tm Align #PB_Structure_AlignC
        tm_sec.l    ; 0 to 59 or up to 60 at leap second
        tm_min.l    ; 0 to 59
        tm_hour.l   ; 0 to 23
        tm_mday.l   ; Day of the month: 1 to 31
        tm_mon.l    ; Month: 0 to 11 (0 = January)
        tm_year.l   ; Number of years since the year 1900
        tm_wday.l   ; Weekday: 0 to 6, 0 = Sunday
        tm_yday.l   ; Days since the beginning of the year: 0 to 365 (365 is therefore 366 because after 1. January is counted)
        tm_isdst.l  ; Is summer time? tm_isdst > 0 = Yes
                    ;                             tm_isdst = 0 = No
                    ;                             tm_isdst < 0 = Unknown
        CompilerIf #PB_Compiler_Processor = #PB_Processor_x86
          tm_gmtoff.l ; Offset of UTC in seconds
          *tm_zone    ; Abbreviation of the time zone
        CompilerElse
          tm_zone.l   ; Placeholder
          tm_gmtoff.l ; Offset of UTC in seconds
          *tm_zone64  ; Abbreviation of the time zone
        CompilerEndIf
        
      EndStructure
      
      ; -- Intern
      
      Procedure secondsFromGMT(utc.q)
        Protected local.q, tm_local.tm
        
        If localtime_r_(@utc, @tm_local) <> 0
          local = timegm_(@tm_local)
          ProcedureReturn local - utc
        Else
          ProcedureReturn 0
        EndIf
      EndProcedure
      
      ; ----
      
      Procedure DateToTimeInfo(Date.q, *TimeInfo.tm, Local = #False)
        Protected r1
        
        If Local
          r1 = localtime_r_(@Date, *TimeInfo)
        Else
          r1 = gmtime_r_(@Date, *TimeInfo)
        EndIf
        ProcedureReturn r1
      EndProcedure
      
      ; ----
      
      Procedure.q TimeInfoToDate(*TimeInfo.tm, Local = #False)
        Protected r1.q, seconds.q
        r1 = timegm_(*TimeInfo)
        If Local
          seconds = secondsFromGMT(r1)
          r1 - seconds
        EndIf
        ProcedureReturn r1
      EndProcedure
      
      ; ----
      
      Procedure GetDateComponent(Component, Date.d, Local = #True)
        Protected r1, vTime.d 
        Static LastDate, Time.tm
        
        If Date <> LastDate
          LastDate = Date
          DateToTimeInfo(Date, Time, Local)
        EndIf
        Select Component
          Case #PB_Date_Year
            ProcedureReturn Time\tm_year + 1900
          Case #PB_Date_Month
            ProcedureReturn Time\tm_mon
          Case #PB_Date_Day
            ProcedureReturn Time\tm_mday
          Case #PB_Date_Hour
            ProcedureReturn Time\tm_hour
          Case #PB_Date_Minute
            ProcedureReturn Time\tm_min
          Case #PB_Date_Second
            ProcedureReturn Time\tm_sec
          Case #PB_Date_Week
            ProcedureReturn Time\tm_wday
        EndSelect
      EndProcedure
      
      ;-- Date functions
      
      Procedure.s GetStringFromDate(Date.d, Mask.s = "%yyyy-%mm-%dd %hh:%ii:%ss", Local = #True)
        Protected r1.s, cnt, vTime.d, Time.tm, milliseconds.d
        
        milliseconds = date - Round(date, #PB_Round_Down)
        DateToTimeInfo(Date, Time, Local)
        ; SystemTime to String
        If Mask = ""
          Mask = "%yyyy-%mm-%dd %hh:%ii:%ss"
        EndIf
        mask = LCase(mask)
        cnt = CountString(mask, "y")
        r1 = RemoveString(Mask, "%")
        If cnt = 2
          r1 = ReplaceString(r1, "yy", RSet(Str(Time\tm_year % 100), 4, "0"))
        Else
          r1 = ReplaceString(r1, "yyyy", RSet(Str(Time\tm_year + 1900), 4, "0"))
        EndIf
        r1 = ReplaceString(r1, "mm", RSet(Str(Time\tm_mon + 1), 2, "0"))
        r1 = ReplaceString(r1, "dd", RSet(Str(Time\tm_mday),2, "0"))
        r1 = ReplaceString(r1, "hh", RSet(Str(Time\tm_hour),2, "0"))
        r1 = ReplaceString(r1, "ii", RSet(Str(Time\tm_min),2, "0"))
        r1 = ReplaceString(r1, "ss", RSet(Str(Time\tm_sec),2, "0"))
        r1 = ReplaceString(r1, "nnn", Right(StrD(milliseconds, 3), 3))
        ProcedureReturn r1
      EndProcedure
      
      ; ----
      
      Procedure.d GetDateFromString(Date.s, Mask.s = "%yyyy-%mm-%dd %hh:%ii:%ss", Local = #True)
        Protected r1.d, pos, cnt, vTime.q, Time.tm, milliseconds.d
        
        ; String to SystemTime
        If Mask = ""
          Mask = "%yyyy-%mm-%dd %hh:%ii:%ss"
        EndIf
        mask = LCase(mask)
        mask = RemoveString(mask, "%")
        cnt = CountString(mask, "y")
        pos = FindString(mask, "y")
        If pos
          Time\tm_year = Val(Mid(Date, pos, cnt)) - 1900
        EndIf
        pos = FindString(mask, "m")
        If pos
          Time\tm_mon = Val(Mid(Date, pos, 2)) - 1
        EndIf
        pos = FindString(Mask, "d")
        If pos
          Time\tm_mday = Val(Mid(Date, pos, 2))
        EndIf
        pos = FindString(Mask, "h")
        If pos
          Time\tm_hour = Val(Mid(Date, pos, 2))
        EndIf
        pos = FindString(Mask, "i")
        If pos
          Time\tm_min = Val(Mid(Date, pos, 2))
        EndIf
        pos = FindString(Mask, "s")
        If pos
          Time\tm_sec = Val(Mid(Date, pos, 2))
        EndIf
        pos = FindString(Mask, "n")
        If pos
          milliseconds = ValD(Mid(Date, pos, 3))
        EndIf
        
        vtime = TimeInfoToDate(Time, Local) 
        r1 = vtime + (milliseconds * 0.001)
        ProcedureReturn r1
      EndProcedure
      
      ; ----
      
      Procedure.d GetDateFromValue(Year, Month, Day, Hour, Minute, Second, Local = #True)
        Protected r1.d, vTime.q, Time.tm
        
        Time\tm_year = Year - 1900
        Time\tm_mon = Month - 1
        Time\tm_mday = Day
        Time\tm_hour = Hour
        Time\tm_min = Minute
        Time\tm_sec = Second
        vtime = TimeInfoToDate(Time, Local) 
        r1 = vtime
        ProcedureReturn r1
      EndProcedure
      
      ; ----
      
      #CLOCK_REALTIME = 0
      
      Structure timespec
        tv_sec.q
        tv_nsec.l
      EndStructure
      
      Import ""
        clock_gettime(clk_id, tv)
        clock_getres(clk_id, res);
      EndImport
      
      Procedure.d GetDateNow()
        Protected r1.d, tv.timespec, vtime.q
        clock_gettime(#CLOCK_REALTIME , @tv)
        vtime = tv\tv_sec * 1000 + ( tv\tv_nsec + 500000 ) / 1000000;
        r1 = vtime * 0.001
        ProcedureReturn r1
      EndProcedure
      
      Procedure.d GetDateNow_Old()
        Protected r1.d, vTime.q
        
        vtime = time_(0)
        r1 = vTime
        ProcedureReturn r1
      EndProcedure
      
      ; ----
      
      Procedure GetSecondsFromGMT()
        Protected r1, vTime.q
        
        vtime = time_(0)
        r1 = secondsFromGMT(vTime)
        ProcedureReturn r1
      EndProcedure
      
      ;-- Calendar functions
      
      Procedure.d GetCalendarDate(Gadget)
        Protected r1.d, vTime.d, Time.tm, now.tm
        Protected year, month, day
        
        DateToTimeInfo(time_(0), now, #True)
        gtk_calendar_get_date_(GadgetID(Gadget), @year, @month, @day)
        Time\tm_year = year - 1900
        Time\tm_mon = month
        Time\tm_mday = day
        Time\tm_hour = now\tm_hour
        Time\tm_min = now\tm_hour
        Time\tm_sec = now\tm_sec
        vTime = TimeInfoToDate(@Time, #True)
        r1 = vTime
        ProcedureReturn r1
      EndProcedure
      
      ; ----
      
      Procedure SetCalendarDate(Gadget, Date.d)
        Protected vTime.d, Time.tm
        
        DateToTimeInfo(Date, @Time, #True)
        gtk_calendar_select_month_(GadgetID(Gadget), Time\tm_mon, Time\tm_year + 1900)
        gtk_calendar_select_day_(GadgetID(Gadget), Time\tm_mday)
        
      EndProcedure
      
  CompilerEndSelect
  
  ;-> Os All
  
  Procedure GetDateYear(Date.d, Local = #True)
    ProcedureReturn GetDateComponent(#PB_Date_Year, Date, Local)
  EndProcedure
  
  Procedure GetDateMonth(Date.d, Local = #True)
    ProcedureReturn GetDateComponent(#PB_Date_Month, Date, Local)
  EndProcedure
  
  Procedure GetDateDay(Date.d, Local = #True)
    ProcedureReturn GetDateComponent(#PB_Date_Day, Date, Local)
  EndProcedure
  
  Procedure GetDateHour(Date.d, Local = #True)
    ProcedureReturn GetDateComponent(#PB_Date_Hour, Date, Local)
  EndProcedure
  
  Procedure GetDateMinute(Date.d, Local = #True)
    ProcedureReturn GetDateComponent(#PB_Date_Minute, Date, Local)
  EndProcedure
  
  Procedure GetDateSecond(Date.d, Local = #True)
    ProcedureReturn GetDateComponent(#PB_Date_Second, Date, Local)
  EndProcedure
  
  Procedure GetDateDayOfWeek(Date.d, Local = #True)
    ProcedureReturn GetDateComponent(#PB_Date_Week, Date, Local)
  EndProcedure
  
EndModule

;- Example 1

CompilerIf #PB_Compiler_IsMainFile
  
  UseModule DateTime
  
  
  Debug "--------"
  Date.d = GetDateNow()
  Debug "Get Date Value Now: " + StrD(date, 3)
  Debug "Get Date Value PB: " + Date()
  sDate.s = GetStringFromDate(Date, "", #False)
  Debug "Get String Now (UTC): " + sDate
  sDate.s = GetStringFromDate(Date, "%yyyy-%mm-%dd %hh:%ii:%ss.%nnn")
  Debug "Get String Now (Local): " + sDate
  Debug "Local to UTC: " + GetSecondsFromGMT()
  Debug "--------"
  Date = Date + (1.0 * 86400.0)
  Debug "One Day Later (Local): " + GetStringFromDate(date)
  Debug "--------"
  Date = GetDateFromString("1865-08-20 00:00:00.100", "%yyyy-%mm-%dd %hh:%ii:%ss.%nnn", #False)
  Debug "Date Value from String (UTC): " + date
  Debug "Date String from Date (UTC): " + GetStringFromDate(Date, "%yyyy-%mm-%dd %hh:%ii:%ss.%nnn", #False)
  Debug "--------"
  Date = GetDateFromString("2065-08-20 00:00:00", "", #False)
  Debug "Date Value from String (UTC): " + date
  Debug "Date String from Date (UTC): " + GetStringFromDate(Date, "", #False)
  Debug "--------"
  Date = GetDateFromString("1965-08-20 00:00:00")
  Debug "Date Value from String (Local): " + date
  Debug "Date String from Date (UTC): " + GetStringFromDate(Date, "", #False)
  Debug "Date String from Date (Local): " + GetStringFromDate(Date)
  Debug "--------"
  Date.d = GetDateNow()
  sDate.s = GetStringFromDate(Date)
  Debug "Get String Now (Local): " + sDate
  Debug "- Year: " + GetDateYear(Date)
  Debug "- Month: " + GetDateMonth(Date)
  Debug "- Day: " + GetDateDay(Date)
  Debug "- Hour: " + GetDateHour(Date)
  Debug "- Minute: " + GetDateMinute(Date)
  Debug "- Secund: " + GetDateSecond(Date)
  Debug "--------"
  Debug "Day Of Week"
  sDate = "2022-08-06 00:00:00"
  Date = GetDateFromString(sDate)
  Debug "Date: " + sDate
  Debug "- PB: " + DayOfWeek(Date(2022,08,06,00,00,00))
  Debug "- MK: " + GetDateDayOfWeek(Date)
  sDate = "2022-08-06 12:00:00"
  Date = GetDateFromString(sDate)
  Debug "Date: " + sDate
  Debug "- PB: " + DayOfWeek(Date(2022,08,06,12,00,00))
  Debug "- MK: " + GetDateDayOfWeek(Date)
  sDate = "2022-08-07 00:00:00"
  Date = GetDateFromString(sDate)
  Debug "Date: " + sDate
  Debug "- PB: " + DayOfWeek(Date(2022,08,07,00,00,00))
  Debug "- MK: " + GetDateDayOfWeek(Date)
  sDate = "2022-08-07 12:00:00"
  Date = GetDateFromString(sDate)
  Debug "Date: " + sDate
  Debug "- PB: " + DayOfWeek(Date(2022,08,07,12,00,00))
  Debug "- MK: " + GetDateDayOfWeek(Date)
  sDate = "2022-08-08 00:00:00"
  Date = GetDateFromString(sDate)
  Debug "Date: " + sDate
  Debug "- PB: " + DayOfWeek(Date(2022,08,08,00,00,00))
  Debug "- MK: " + GetDateDayOfWeek(Date)
  sDate = "2022-08-08 12:00:00"
  Date = GetDateFromString(sDate)
  Debug "Date: " + sDate
  Debug "- PB: " + DayOfWeek(Date(2022,08,08,12,00,00))
  Debug "- MK: " + GetDateDayOfWeek(Date)
  
  Debug "--------"
  sDate = "2022-08-08 12:00:00"
  Date1.d = GetDateFromString(sDate)
  Date2.d = GetDateFromValue(2022,08,08,12,00,00)
  Debug Date1
  Debug Date2
  Debug GetStringFromDate(Date2)
  
CompilerEndIf
Last edited by mk-soft on Sat Nov 19, 2022 5:00 pm, edited 16 times in total.
My Projects ThreadToGUI / OOP-BaseClass / EventDesigner V3
PB v3.30 / v5.75 - OS Mac Mini OSX 10.xx - VM Window Pro / Linux Ubuntu
Downloads on my Webspace / OneDrive
User avatar
mk-soft
Always Here
Always Here
Posts: 5335
Joined: Fri May 12, 2006 6:51 pm
Location: Germany

Re: [Window, MacOS] Module DateTime - Date as Double Since 1

Post by mk-soft »

Example CalendarGadget

Code: Select all

;-TOP

EnableExplicit

XIncludeFile "Modul_DateTime.pb"

UseModule DateTime

Enumeration Windows
  #Main
EndEnumeration

Enumeration Gadgets
  #Calendar1
  #Calendar2
  #Calendar3
  #List
EndEnumeration

Enumeration Status
  #MainStatusBar
EndEnumeration

CompilerSelect #PB_Compiler_OS
    
  CompilerCase #PB_OS_Windows
  
    ; Create gadget eventtype change for CalendarGadget
    
    #MCN_SELECT = -746
    
    Procedure CalendarGadget_WindowCB(hWnd,uMsg,wParam,lParam)
      Protected *NMHDR.NMHDR
      Select uMsg
        Case #WM_NOTIFY
          *NMHDR = lParam
          If IsGadget(*NMHDR\idFrom) And GadgetType(*NMHDR\idFrom) = #PB_GadgetType_Calendar
            If *NMHDR\code = #MCN_SELECT
              PostEvent(#PB_Event_Gadget, 0, *NMHDR\idFrom, #PB_EventType_Change)
            EndIf
          EndIf
      EndSelect
      ProcedureReturn #PB_ProcessPureBasicEvents
    EndProcedure
    
    SetWindowCallback(@CalendarGadget_WindowCB())
    
  CompilerCase #PB_OS_MacOS
    
    
CompilerEndSelect

Procedure LogDate(Date.d)
  AddGadgetItem(#List, -1, "Calendar 1 Local: " + GetStringFromDate(date))
  AddGadgetItem(#List, -1, "Calendar 1 UTC: " + GetStringFromDate(date, "", 0))
  SetGadgetState(#List, CountGadgetItems(#List) - 1)
  SetGadgetState(#List, -1)
EndProcedure

Procedure Main()
  Protected date1.d, date2.d, date3.d
  
  #MainStyle = #PB_Window_SystemMenu | #PB_Window_MaximizeGadget | #PB_Window_MinimizeGadget
  
  
  If OpenWindow(#Main, #PB_Ignore, #PB_Ignore, 800, 600, "Window" , #MainStyle)
    
    CalendarGadget(#Calendar1, 10, 10, 180, 180)
    CalendarGadget(#Calendar2, 200, 10, 180, 180)
    CalendarGadget(#Calendar3, 390, 10, 180, 180)
    ListViewGadget(#List, 10, 200, 780, 380)
    
    SetCalendarDate(#Calendar1, GetDateFromString("1965-08-20 12:00:00"))
    SetCalendarDate(#Calendar2, GetDateNow())
    SetCalendarDate(#Calendar3, GetDateFromString("2065-08-20 12:00:00"))
    
    date1 = GetCalendarDate(#Calendar1)
              LogDate(date1)
              
    Repeat
      Select WaitWindowEvent()
        Case #PB_Event_CloseWindow
          Break
        Case #PB_Event_Gadget
          Select EventGadget()
            Case #Calendar1
              date1 = GetCalendarDate(#Calendar1)
              LogDate(date1)
              
            Case #Calendar2
              date2 = GetCalendarDate(#Calendar2)
              LogDate(date2)
              
            Case #Calendar3
              date3 = GetCalendarDate(#Calendar3)
              LogDate(date3)
              
          EndSelect
          
      EndSelect
    ForEver
    
  EndIf
  
EndProcedure : Main()
Last edited by mk-soft on Tue Aug 09, 2022 7:14 pm, edited 5 times in total.
My Projects ThreadToGUI / OOP-BaseClass / EventDesigner V3
PB v3.30 / v5.75 - OS Mac Mini OSX 10.xx - VM Window Pro / Linux Ubuntu
Downloads on my Webspace / OneDrive
User avatar
Saki
Addict
Addict
Posts: 830
Joined: Sun Apr 05, 2020 11:28 am
Location: Pandora

Re: [Window, MacOS] Module DateTime - Date as Double Since 1

Post by Saki »

Very nice,
Are you still trying Linux ?
I'm sure someone has a solution for Linux that he could contribute here
地球上の平和
User avatar
mk-soft
Always Here
Always Here
Posts: 5335
Joined: Fri May 12, 2006 6:51 pm
Location: Germany

Re: [Window, MacOS] Module DateTime - Date as Double Since 1

Post by mk-soft »

Saki wrote:Very nice,
Are you still trying Linux ?
I'm sure someone has a solution for Linux that he could contribute here
I haven't found anything useful in the Linux documents.

In fact, Wilbert's module "Date64" is the best.
So the module here is actually obsolete and it is perhaps better to extend the module from Wilbert the DateGadget and Calendar functions for all OS (I am currently doing this).

But I will work on these modules again.

The DateGadget from Purebasic under MacOS is not usable and should be replaced by "Module OSX_DateGadget". For the Calendar Gadget from linux I have to check how the date is set.
My Projects ThreadToGUI / OOP-BaseClass / EventDesigner V3
PB v3.30 / v5.75 - OS Mac Mini OSX 10.xx - VM Window Pro / Linux Ubuntu
Downloads on my Webspace / OneDrive
User avatar
Saki
Addict
Addict
Posts: 830
Joined: Sun Apr 05, 2020 11:28 am
Location: Pandora

Re: [Window, MacOS] Module DateTime - Date as Double Since 1

Post by Saki »

Hi, yes, I know the module from Wilbert.
The question in itself is why it is not integrated in PB ?

Nevertheless, I appreciate your work as a small separate solution, which is easy to use, without ASM, also has its advantages.
地球上の平和
BarryG
Addict
Addict
Posts: 3292
Joined: Thu Apr 18, 2019 8:17 am

Re: [Window, MacOS] Module DateTime - Date as Double Since 1

Post by BarryG »

Saki wrote:why it is not integrated in PB ?
We've been requesting native long date ranges for years, and it's never been done and we've never been given a reason why. It's one of those weird silent PureBasic issues.

I've been using Wilbert's "Date64" module for about 2 years now instead, just so my app (which has calendar functionality) can cope.
User avatar
Sicro
Enthusiast
Enthusiast
Posts: 538
Joined: Wed Jun 25, 2014 5:25 pm
Location: Germany
Contact:

Re: [Window, MacOS] Module DateTime - Date as Double Since 1

Post by Sicro »

@mk-soft:
Your codes are always very good and cleanly written. Thanks a lot. :-)
I just don't understand why we reinvent the wheel over and over again. The CodeArchiv project on GitHub is actually intended to collaborate on existing codebases and extend these together.

@Saki:
In the PB-CodeArchiv project on GitHub is a Date64 module that also supports extended date ranges, for Windows, Linux and macOS: Click
(but currently not support the DateGadget and the CalendarGadget)

@BarryG:
Yes, native support would be the best way.

@All:
I also find the ASM codes from Wilbert great, especially when speed is important, but when errors occur, you have to rely on people who have ASM knowledge, if you don't have it yourself.

Many people here are obviously not interested in OpenSource licenses, but nobody will use the codes if they don't have a license and they want to produce serious software projects.

Posting PB module codes on the forum is convenient, but this usually gives no way to access previous versions if there is no backup anywhere else. Then what if the current version is buggy? Then what if the current version brings API changes that require your own code to be adapted, but you don't have time to adapt it and want to use the previous version until you have enough time for the adaption?
Image
Why OpenSource should have a license :: PB-CodeArchiv-Rebirth :: Pleasant-Dark (syntax color scheme) :: RegEx-Engine (compiles RegExes to NFA/DFA)
Manjaro Xfce x64 (Main system) :: Windows 10 Home (VirtualBox) :: Newest PureBasic version
User avatar
Saki
Addict
Addict
Posts: 830
Joined: Sun Apr 05, 2020 11:28 am
Location: Pandora

Re: [Window, MacOS] Module DateTime - Date as Double Since 1

Post by Saki »

@Barry
Yes, this is a strange thing.
i think there should be no dependencies or liabilities.

@Sicro
You are doing a lot of work with git.
But for whom and for what ?
I think you are suffocating by now in the many thank you letters you get for it.

When I search something in the forum I usually ask Google.
Old versions are usually worse than new ones.
And try what still runs with PB what was up to date 10 years ago.

I would also be very happy if PureArea.net would get new color in the long run.
I think when Andre has finished his project this will follow.

The 32Bit Unix Time should really be long gone from PB, this is computer stone age.

If a project exists as exekutable which uses this, it can indeed no longer be used after 2038.
be used anymore.
There are projects, which can be relevant also after this time or an access is necessary for any reasons.

The time passes faster than one thinks, still 50 times Lockdown in Germany, then is 2038 :o

I myself make my tools for PB free of charge.
Almost everyone here does that.

So everyone has something from it and whether someone uses my codes or not I don't care at all,
that's why they are created, so that everyone has something from it.
It is also a promotion for PB itself to support this very good and inexpensive product.

Who wants to sell something in the forum should disappear and not constantly nerf with promotional pushing,
that does not belong here purely. :evil:
地球上の平和
User avatar
mk-soft
Always Here
Always Here
Posts: 5335
Joined: Fri May 12, 2006 6:51 pm
Location: Germany

Re: [Window, MacOS] Module DateTime - Date as Double Since 1

Post by mk-soft »

Fortunately, I will retire in 2038. But I'm afraid that I'll still be picked up then, as some of my programmes will still be running, even though the machines would have to be scrap by then.
My Projects ThreadToGUI / OOP-BaseClass / EventDesigner V3
PB v3.30 / v5.75 - OS Mac Mini OSX 10.xx - VM Window Pro / Linux Ubuntu
Downloads on my Webspace / OneDrive
BarryG
Addict
Addict
Posts: 3292
Joined: Thu Apr 18, 2019 8:17 am

Re: [Window, MacOS] Module DateTime - Date as Double Since 1

Post by BarryG »

mk-soft wrote:Fortunately, I will retire in 2038.
It's not about waiting for 2038 to arrive to break our apps. They're already broken if they do any date calculations into the future, like mine. If it weren't for Wilbert's Date64 module to handle those calcs then my app would be dead already.
User avatar
mk-soft
Always Here
Always Here
Posts: 5335
Joined: Fri May 12, 2006 6:51 pm
Location: Germany

Re: [Window, MacOS] Module DateTime - Date as Double Since 1

Post by mk-soft »

MacOS has the NSDate object. Windows has the ole automation VariantTime. Only Linux does not provide anything comparable in the system. Even time64_t has problems with dates before 1970.

Here a big thanks to wilbert for his work.
The comparison of the result between NSDate, VariantTime and Wilber's Date64 also looks very good. Everything is correct down to the second.

Wilbert's Date64 should be adopted internally by Fred.

Over Easter (thanks to corona :( ), the CalendarGadget and DateGadget functions for all three OS should be ready.
My Projects ThreadToGUI / OOP-BaseClass / EventDesigner V3
PB v3.30 / v5.75 - OS Mac Mini OSX 10.xx - VM Window Pro / Linux Ubuntu
Downloads on my Webspace / OneDrive
User avatar
Sicro
Enthusiast
Enthusiast
Posts: 538
Joined: Wed Jun 25, 2014 5:25 pm
Location: Germany
Contact:

Re: [Window, MacOS] Module DateTime - Date as Double Since 1

Post by Sicro »

Saki wrote:You are doing a lot of work with git.
But for whom and for what ?
Because Git is a version control software and version control is a must-have in development.
Saki wrote:When I search something in the forum I usually ask Google.
With a Google search you get to the appropriate forum threads, yes, but then you have to copy the code out of the forum post. What if the code consists of several files? Then there is a link to a file hoster where you probably have to solve a captcha before you can download the zip file, etc.
Saki wrote:Old versions are usually worse than new ones.
And try what still runs with PB what was up to date 10 years ago.
Yes, but as I wrote in the previous post, there are reasons to want to continue using older versions. That's why there is also a LTS version of PureBasic.
Saki wrote:I myself make my tools for PB free of charge.
Almost everyone here does that.

So everyone has something from it and whether someone uses my codes or not I don't care at all,
that's why they are created, so that everyone has something from it.
It is also a promotion for PB itself to support this very good and inexpensive product.

Who wants to sell something in the forum should disappear and not constantly nerf with promotional pushing,
that does not belong here purely.
Yes, sure. Apparently you misunderstand something: OpenSource licenses are not there to sell something, but they automatically give you the right to use the codes and do different things with them without having to ask the copyright owner.

If someone presents a commercial product that is PureBasic relevant, I don't think the PureBasic forum is the wrong area for it. But sure, spamming the forum with it is not good then.
mk-soft wrote:MacOS has the NSDate object. Windows has the ole automation VariantTime. Only Linux does not provide anything comparable in the system. Even time64_t has problems with dates before 1970.
My last tests are now quite a while back in time, but this was the test result of the Date64 module from the CodeArchiv, which uses the time_() API under Linux:

Code: Select all

; == Linux ==
; 32-Bit:
; >> Minimum: 01.01.1902 00:00:00
; >> Maximum: 18.01.2038 23:59:59
; 64-Bit:
; >> Minimum: 01.01.0000 00:00:00
; >> Maximum: 31.12.9999 23:59:59
If I remember correctly, I recently read that a 64-bit timestamp is used in newer Linux kernel versions even on 32-bit systems.

Do you have an example that shows the problem before 1970?
mk-soft wrote:Wilbert's Date64 should be adopted internally by Fred.
That would be very good, yes.
mk-soft wrote:Over Easter (thanks to corona :( ), the CalendarGadget and DateGadget functions for all three OS should be ready.
Sounds great, I'm curious.
Image
Why OpenSource should have a license :: PB-CodeArchiv-Rebirth :: Pleasant-Dark (syntax color scheme) :: RegEx-Engine (compiles RegExes to NFA/DFA)
Manjaro Xfce x64 (Main system) :: Windows 10 Home (VirtualBox) :: Newest PureBasic version
Bitblazer
Enthusiast
Enthusiast
Posts: 733
Joined: Mon Apr 10, 2017 6:17 pm
Location: Germany
Contact:

Re: [Window, MacOS] Module DateTime - Date as Double Since 1

Post by Bitblazer »

Sicro wrote:Posting PB module codes on the forum is convenient, but this usually gives no way to access previous versions if there is no backup anywhere else. Then what if the current version is buggy? Then what if the current version brings API changes that require your own code to be adapted, but you don't have time to adapt it and want to use the previous version until you have enough time for the adaption?
Like many other old time users here, i did often run into sources and example / tool links to private websites, source repositories, ftp hosts etc. which disappeared throughout the years. Actually posting a source on the purebasic forum, was by far the most reliable and stable archive method. Here have a look at the PureBasic forum from 20 years ago thanks to the Wayback machine.

Forum articles have been moved over from old forum versions and the wayback archive is quite reliable so far. Posting a source on the forum, has been so reliable, that i wrote my own encoding/decoding/upload tools to support it.

The real downside i see, is that it would create too much resource use (cost) for the forum if we started to post all "important" sources to a subsection of the forum ;)

But maybe essential snippets of max 75 lines would be acceptable.

Oh and about the "keeping old nonbuggy versions" point. At the time you use a modules, you compile it with a copy of the modules on your storage anyway. Simply create backups of any working project. Archive it whenever a project has a working or significant status (like a release version always should be archived for years for commercial projects). Storage is dirt cheap nowadays and you can always use strong enrcyption if you have valuable private data to store. If you are paranoid - simply use multiple rounds and levels of encryption before uploading anything. But don't forget the password(s) and make sure the decryption tools are archived too ;)
webpage - discord chat links -> purebasic GPT4All
User avatar
Saki
Addict
Addict
Posts: 830
Joined: Sun Apr 05, 2020 11:28 am
Location: Pandora

Re: [Window, MacOS] Module DateTime - Date as Double Since 1

Post by Saki »

@Sicro
There is always a difference between theory and practice.
In theory, everything you say is correct.

Practically, hardly anyone will be interested in whether codes from the forum are integrated into a software.

Primarily here in the forum 99.99% of the users create software to support and help each other for free.

Or just to promote PB for free, because they appreciate the project and want to keep it alive.
It's like fuel for a car, what good is the most beautiful car without fuel ?

Furthermore, probably no one will notice or determine this.
With a niche software it will not be public anyway and it is not immediately visible whether the software was created with PB or whatever.

So there is always a difference, you are not allowed to do everything, but people tend to do what they are not allowed to do or should not do. :evil:
地球上の平和
User avatar
mk-soft
Always Here
Always Here
Posts: 5335
Joined: Fri May 12, 2006 6:51 pm
Location: Germany

Re: [All OS] Module DateTime - Date as Double Since 1970

Post by mk-soft »

Update v1.02.0
- added linux

I borrowed the code for Linux from Wilbert and modified it.
The Linux version is not quite perfect with the "Locale" option.

Link to Date64:
Source: viewtopic.php?f=12&t=56031
Module: viewtopic.php?p=421612#p478507
My Projects ThreadToGUI / OOP-BaseClass / EventDesigner V3
PB v3.30 / v5.75 - OS Mac Mini OSX 10.xx - VM Window Pro / Linux Ubuntu
Downloads on my Webspace / OneDrive
Post Reply