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