Hi all
Is there a quick and simply way to calculate the difference in day between two date ?
ex 26/03/2021 compare with 24/03/2021 Result 2 days
Yhanks in advance
DateDiff question
Re: DateDiff question
Code: Select all
Debug (Date (2021, 03, 31, 00, 00, 00) - Date (2021, 03, 29, 00, 00, 00)) / 60 / 60 / 24
sorry for my bad english
Re: DateDiff question
Code: Select all
ImportC "msvcrt.lib"
swprintf(*s, Format.s, Param1=0, Param2=0, Param3=0, Param4=0, Param5=0, Param6=0)
EndImport
Error_Procedure = 0
; AutoIt3 UDF
Procedure _DateIsLeapYear(Year)
If Mod(Year, 4) = 0 And Mod(Year, 100) <> 0
ProcedureReturn 1
ElseIf Mod(Year, 400) = 0
ProcedureReturn 1
Else
ProcedureReturn 0
EndIf
EndProcedure
; @AZJIO
Procedure __DateDiff_2(Array Old(1), Array New(1), Array R(1))
Protected i, t = 0, Dim L(5)
L(0) = 5 ; не используется, размер массива
L(1) = 12; месяцев в годе
L(2) = 0 ; дней в месяце, определяется по условию
L(3) = 24; часов в дне
L(4) = 60; минут в часе
L(5) = 60; секунд в минуте
For i = 5 To 1 Step -1
If i = 2
Select Old(1)
Case 1, 3, 5, 7, 8, 10, 12 ; месяца в которых 31 день
L(i) = 31
Case 2
If _DateIsLeapYear(Old(0)) ; если високосный год, то в феврале:
L(i) = 29
Else
L(i) = 28
EndIf
Default ; в остальных 30 дней
L(i) = 30
EndSelect
EndIf
; тут метод вычитания с заёмом
If (New(i) - t) < Old(i)
R(i) = New(i) + L(i) - t - Old(i)
t = 1
Else
R(i) = New(i) - t - Old(i)
t = 0
EndIf
Next
R(0) = New(0) - Old(0) - t ; отдельно для годов
ProcedureReturn
EndProcedure
; @AZJIO
Procedure.s DateDiff_2(Array Old(1), Array New(1))
If ArraySize(Old()) < 5 ; проверка размера массива
Error_Procedure = -1
ProcedureReturn
EndIf
If ArraySize(New()) < 5
Error_Procedure = -2
ProcedureReturn
EndIf
Protected Extended = 0 ; дополнительный параметр, определяет что старая дата больше новой
Protected Dim R(6) ; массив для результата
R(0) = 0
R(1) = 0
R(2) = 0
R(3) = 0
R(4) = 0
R(5) = 0
; Цикл определяет какая дата больше или новее
For i = 0 To 5
If Old(i) <> New(i) ; если элементы не равны, то только тогда можно выявить старшинство, иначе переходим к младшему разряду - следующий шаг цикла
If Old(i) < New(i) ; еслпи старая меньше (как и должно быть), то вызываем в первом параметре старый
__DateDiff_2(Old(), New(), R())
Else ; иначе вызываем новый как старый в первом параметре
__DateDiff_2(New(), Old(), R())
Extended = 1
EndIf
Break
EndIf
Next
; Можно было бы переделать на возврат массива (по ссылке), но делаем строкой
Protected Buff.s{100}
swprintf(@Buff, "%d.%02d.%02d %02d:%02d:%02d", R(0), R(1), R(2), R(3), R(4), R(5))
If Extended
Buff = "-" + Buff
EndIf
ProcedureReturn Buff
EndProcedure
Dim date1(5)
date1(0) = 2018
date1(1) = 4
date1(2) = 12
date1(3) = 12
date1(4) = 30
date1(5) = 10
Dim date2(5)
date2(0) = 2019
date2(1) = 4
date2(2) = 12
date2(3) = 1
date2(4) = 31
date2(5) = 9
; не обязательно указывать дату, можно указать только время, тогда получим разницу только времени.
; смотрите также ParseDate(), обратную ей FormatDate() Date()
Debug DateDiff_2(date1(), date2()) ; в формате 12.03.24 04:16:14
- NicTheQuick
- Addict
- Posts: 1510
- Joined: Sun Jun 22, 2003 7:43 pm
- Location: Germany, Saarbrücken
- Contact:
Re: DateDiff question
I wonder when the Date library will finally be able to use 64 bit integers and dates after the year 2038.
I am also not able to make calculations with dates before 1970. I wish there were a second Date library natively which can do all of this.
I am also not able to make calculations with dates before 1970. I wish there were a second Date library natively which can do all of this.
The english grammar is freeware, you can use it freely - But it's not Open Source, i.e. you can not change it or publish it in altered way.
Re: DateDiff question
For this to work on Linux, you need to replace the swprintf function
Format.pb
another option:
i did it based on my function
Format.pb
Code: Select all
XIncludeFile "Format.pb"
...
Protected Buff.s
Buff = Format( "%i.%02i.%02i %02i:%02i:%02i", @R(0), @R(1), @R(2), @R(3), @R(4), @R(5))
Code: Select all
ImportC ""
sprintf(*str, format.p-utf8, Param1=0, Param2=0, Param3=0, Param4=0, Param5=0, Param6=0)
EndImport
...
sprintf(@Buff, "%d.%02d.%02d %02d:%02d:%02d", R(0), R(1), R(2), R(3), R(4), R(5))
Buff = PeekS(@Buff, -1, #PB_UTF8)
- DeanH
- Enthusiast
- Posts: 274
- Joined: Wed May 07, 2008 4:57 am
- Location: Adelaide, South Australia
- Contact:
Re: DateDiff question
64-bit date functions are available. Wilbert posted a good set of procedures called Date64, and it has been updated by others. I have been using them successfully for several years. They cover years from 1582 to 9999.
http://www.purebasic.fr/english/viewtop ... 12#p421612
In order to calculate days apart, I convert regular gregorian date format to julian format and subtract. Julian dates are a number of days. I cannot recall where I first saw these but it was way back in the 1980's.
I'm sure the Date64 library could be used, too.
http://www.purebasic.fr/english/viewtop ... 12#p421612
In order to calculate days apart, I convert regular gregorian date format to julian format and subtract. Julian dates are a number of days. I cannot recall where I first saw these but it was way back in the 1980's.
Code: Select all
;Convert gregorian date to julian
;Input D$ in DD/MM/YYYY format
Procedure.l GregorianToJulianDate(d$)
Protected w,jg.l,b,mm,yy,dd,p,mm$
dd=Val(Left(d$,2))
mm=Val(Mid(d$,4,2))
yy=Val(Right(d$,4))
w=Int((mm-14)/12)
jg=Int(1461*(yy+4800+w)/4)
b=Int(367*(mm-2.-w*12)/12)
jg=jg+b
b=Int(Int(3*(yy+4900+w)/100)/4)
jg=jg+dd-32075-b
ProcedureReturn jg
EndProcedure
Procedure$ JulianToGregorianDate(jg.l)
Protected w,r,z,n,dd,mm,yy
w=jg+68569 ;2520749
r=Int(4*w/146097) ;69
w=w-Int((146097*r+3)/4) ;575
z=Int(4000*(w+1)/1461001) ;1
w=w-Int(1461*z/4)+31 ;241
n=Int(80*w/2447) ;7
dd=w-Int(2447*n/80) ;29 day
w=Int(n/11) ;0
mm=n+2-12*w ;9 month
yy=100*(r-49)+z+w ;2001 year
d$=RSet(Str(dd),2,"0")+"/"+RSet(Str(mm),2,"0")+"/"+Str(yy)
ProcedureReturn d$
EndProcedure
;To get the difference between 25/03/2021 and 16/03/2021, use something like
jd1 = GregorianToJulianDate("25/03/2021")
jd2 = GregorianToJulianDate("16/03/2021")
Debug jd1
Debug jd2
DateDiff = Abs(jd1-jd2)
Debug DateDiff
;Should show in the debug window
;2459299
;2459290
;9
Re: DateDiff question
Only Windows ...
Code: Select all
Procedure SetDateToSystemTime(vTime.d,*Time.SystemTime)
Protected r1
r1 = VariantTimeToSystemTime_(vTime, *Time)
ProcedureReturn r1
EndProcedure
Procedure.d GetDateFromSystemTime(*Time.SystemTime)
Protected r1, vTime.d
r1 = SystemTimeToVariantTime_(*Time, @vTime)
ProcedureReturn vtime
EndProcedure
Procedure SetSystemTime(*Time.SystemTime, Year, Month, Day, Hour = 0, Minute = 0, Second = 0)
With *Time
\wYear = Year
\wMonth = Month
\wDay = Day
\wHour = Hour
\wMinute = Minute
\wSecond = Second
\wMilliseconds = 0
EndWith
EndProcedure
Global systime1.SystemTime
Global systime2.SystemTime
Global date1.d, date2.d, date3.d
GetLocalTime_(systime1)
SetSystemTime(systime2, 1965, 08, 20, 15, 30)
date1 = GetDateFromSystemTime(systime1)
date2 = GetDateFromSystemTime(systime2)
date3 = date1 - date2
Debug "I am " + StrD(date3, 2) + " days old"
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
PB v3.30 / v5.75 - OS Mac Mini OSX 10.xx - VM Window Pro / Linux Ubuntu
Downloads on my Webspace / OneDrive
Re: DateDiff question
For macOS ...
Code: Select all
;-TOP
; ----
;- MacOS Date funtions
; 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
Macro CocoaString(NSString)
PeekS(CocoaMessage(0, NSString, "UTF8String"), -1, #PB_UTF8)
EndMacro
Procedure.s GetStringFromDate(Date, Mask.s = "yyyy-MM-dd")
Protected NSPool, NSDateFormatter, NSString
Protected r1.s
NSPool = CocoaMessage(0, 0, "NSAutoreleasePool new")
NSDateFormatter = CocoaMessage(0, 0, "NSDateFormatter new")
; Convert PB date format
If FindString(Mask, "%")
mask = LCase(mask)
mask = ReplaceString(mask, "m", "M")
mask = ReplaceString(mask, "i", "m")
mask = ReplaceString(mask, "h", "H")
mask = RemoveString(mask, "%")
EndIf
If Date = 0
Date = CocoaMessage(0, 0, "NSDate date")
EndIf
CocoaMessage(0, NSDateFormatter, "setDateFormat:$", @Mask)
NSString = CocoaMessage(0, NSDateFormatter, "stringFromDate:@", @Date)
r1 = CocoaString(NSString)
CocoaMessage(0, NSDateFormatter, "release")
CocoaMessage(0, NSPool, "release")
ProcedureReturn r1
EndProcedure
Procedure GetDateFromString(Date.s = "now", Mask.s = "yyyy-MM-dd")
Protected NSPool, NSDate, NSDateFormatter
Protected r1
NSPool = CocoaMessage(0, 0, "NSAutoreleasePool new")
NSDateFormatter = CocoaMessage(0, 0, "NSDateFormatter new")
If date = "now"
r1 = CocoaMessage(0, 0, "NSDate now")
Else
; Convert PB date format
If FindString(Mask, "%")
mask = LCase(mask)
mask = ReplaceString(mask, "m", "M")
mask = ReplaceString(mask, "i", "m")
mask = ReplaceString(mask, "h", "H")
mask = RemoveString(mask, "%")
EndIf
CocoaMessage(0, NSDateFormatter, "setDateFormat:$", @Mask)
r1 = CocoaMessage(0, NSDateFormatter, "dateFromString:$", @Date)
EndIf
CocoaMessage(0, NSDateFormatter, "release")
CocoaMessage(0, NSPool, "release")
ProcedureReturn r1
EndProcedure
; ----
Define diff.d
Define date1 = GetDateFromString()
Define date2 = GetDateFromString("1965-08-20 15:30:00", "%YYYY-%MM-%DD %HH:%II:%SS")
;Define date2 = CocoaMessage(0, 0, "NSDate dateWithString:$", @"1965-08-20 14:30:00 +0000")
Debug GetStringFromDate(date1, "%YYYY-%MM-%DD %hh:%II:%SS")
Debug GetStringFromDate(date2, "%YYYY-%MM-%DD %hh:%II:%SS")
r1 = CocoaMessage(@diff, date1, "timeIntervalSinceDate:", date2)
Debug "I am " + StrD(diff / 86400.0, 2) + " days old"
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
PB v3.30 / v5.75 - OS Mac Mini OSX 10.xx - VM Window Pro / Linux Ubuntu
Downloads on my Webspace / OneDrive