Calculate the number of days between two dates.
Date input should be of the form YYYY-MM-DD.
To demonstrate one of the numerous ways this can be done.
F parse_date(date) R time:strptime(date, ‘%Y-%m-%d’)V date1 = parse_date(‘2019-01-01’)V date2 = parse_date(‘2019-09-30’)print((date2 - date1).days())
272
INCLUDE "D2:REAL.ACT" ;from the Action! Tool KitTYPE Date=[CARD year BYTE month,day]BYTE FUNC IsLeapYear(CARD y) IF y MOD 100=0 THEN IF y MOD 400=0 THEN RETURN (1) ELSE RETURN (0) FI FI IF y MOD 4=0 THEN RETURN (1) FIRETURN (0)PROC DecodeDate(CHAR ARRAY s Date POINTER d) BYTE ARRAY maxD=[0 31 28 31 30 31 30 31 31 30 31 30 31] CHAR ARRAY tmp(5) BYTE m IF s(0)#10 THEN Break() FI SCopyS(tmp,s,1,4) d.year=ValC(tmp) SCopyS(tmp,s,6,7) d.month=ValB(tmp) SCopyS(tmp,s,9,10) d.day=ValB(tmp) IF d.year=0 OR d.month=0 OR d.month>12 OR d.day=0 THEN Break() FI IF IsLeapYear(d.year) THEN maxD(2)=29 ELSE maxD(2)=28 FI m=d.month IF d.day>maxD(m) THEN Break() FIRETURNPROC DateToDays(Date POINTER d REAL POINTER res) BYTE m INT y,tmp1 REAL tmp2 m=(d.month+9) MOD 12 y=d.year-m/10 tmp1=y/4-y/100+y/400+(m*306+5)/10+(d.day-1) IntToReal(365,res) IntToReal(y,tmp2) RealMult(res,tmp2,res) IntToReal(tmp1,tmp2) RealAdd(res,tmp2,res)RETURNPROC DiffDays(Date POINTER d1,d2 REAL POINTER diff) REAL days1,days2 DateToDays(d1,days1) DateToDays(d2,days2) RealSub(days2,days1,diff)RETURNPROC Test(CHAR ARRAY s1,s2) Date d1,d2 REAL diff DecodeDate(s1,d1) DecodeDate(s2,d2) DiffDays(d1,d2,diff) PrintF("%S .. %S -> ",s1,s2) PrintRE(diff)RETURNPROC Main() Put(125) PutE() ;clear the screen Test("1995-11-21","1995-11-21") Test("2019-01-01","2019-01-02") Test("2019-01-02","2019-01-01") Test("2019-01-01","2019-03-01") Test("2020-01-01","2020-03-01") Test("1902-01-01","1968-12-25") Test("2090-01-01","2098-12-25") Test("1902-01-01","2098-12-25")RETURNScreenshot from Atari 8-bit computer
1995-11-21 .. 1995-11-21 -> 02019-01-01 .. 2019-01-02 -> 12019-01-02 .. 2019-01-01 -> -12019-01-01 .. 2019-03-01 -> 592020-01-01 .. 2020-03-01 -> 601902-01-01 .. 1968-12-25 -> 244652090-01-01 .. 2098-12-25 -> 32801902-01-01 .. 2098-12-25 -> 71947
withAda.Calendar;withAda.Text_IO;withAda.Integer_Text_IO;withGNAT.Calendar.Time_IO;procedureDays_Between_DatesisfunctionDays_Between(Lower_Date:inAda.Calendar.Time;Higher_Date:inAda.Calendar.Time)returnIntegerisuseAda.Calendar;Diff:constantDuration:=Higher_Date-Lower_Date;beginreturnInteger(Diff/Day_Duration'Last);endDays_Between;procedurePut_Days_Between(Lower_Date:inString;Higher_Date:inString;Comment:inString)isuseAda.Text_IO;useAda.Integer_Text_IO;useGNAT.Calendar.Time_IO;Diff:constantInteger:=Days_Between(Lower_Date=>Value(Lower_Date),Higher_Date=>Value(Higher_Date));beginPut("Days between "&Lower_Date&" and "&Higher_Date&" is ");Put(Diff,Width=>5);Put(" days -- ");Put(Comment);New_Line;endPut_Days_Between;beginPut_Days_Between("1995-11-21","1995-11-21","Identical dates");Put_Days_Between("2019-01-01","2019-01-02","Positive span");Put_Days_Between("2019-01-02","2019-01-01","Negative span");Put_Days_Between("2019-01-01","2019-03-01","Non-leap year");Put_Days_Between("2020-01-01","2020-03-01","Leap year");Put_Days_Between("1902-01-01","1968-12-25","Past");Put_Days_Between("2090-01-01","2098-12-25","Future");Put_Days_Between("1902-01-01","2098-12-25","Long span");endDays_Between_Dates;
Days between 1995-11-21 and 1995-11-21 is 0 days -- Identical datesDays between 2019-01-01 and 2019-01-02 is 1 days -- Positive spanDays between 2019-01-02 and 2019-01-01 is -1 days -- Negative spanDays between 2019-01-01 and 2019-03-01 is 59 days -- Non-leap yearDays between 2020-01-01 and 2020-03-01 is 60 days -- Leap yearDays between 1902-01-01 and 1968-12-25 is 24465 days -- PastDays between 2090-01-01 and 2098-12-25 is 3280 days -- FutureDays between 1902-01-01 and 2098-12-25 is 71947 days -- Long span
BEGIN # calculate the number of days between a pair of dates # # based on a translation of the FreeBASIC sample # [,]STRING test cases = ( ( "1902-01-01", "1968-12-25" ) , ( "2019-01-01", "2019-01-02" ), ( "2019-01-02", "2019-01-01" ) , ( "2019-01-01", "2019-03-01" ), ( "2020-01-01", "2020-03-01" ) , ( "1995-11-21", "1995-11-21" ), ( "2090-01-01", "2098-12-25" ) ); PROC gregorian = ( INT y, m, d )INT: BEGIN INT n = ( m + 9 ) - ( ( ( m + 9 ) OVER 12 ) * 12 ); INT w = y - ( n OVER 10 ); ( 365 * w ) + ( w OVER 4 ) - ( w OVER 100 ) + ( w OVER 400 ) + ( ( ( n * 306 ) + 5 ) OVER 10 ) + ( d - 1 ) END # gregorian # ; OP TOINT = ( STRING s )INT: BEGIN INT v := 0; FOR s pos FROM LWB s TO UPB s DO v *:= 10 +:= ( ABS s[ s pos ] - ABS "0" ) OD; v END # TOINT #; FOR n FROM LWB test cases TO UPB test cases DO STRING from date = test cases[ n, 1 ]; STRING to date = test cases[ n, 2 ]; INT from g = gregorian( TOINT from date[ 1 : 4 ] , TOINT from date[ 6 : 7 ] , TOINT from date[ 9 : 10 ] ); INT to g = gregorian( TOINT to date[ 1 : 4 ] , TOINT to date[ 6 : 7 ] , TOINT to date[ 9 : 10 ] ); print( ( "Days between ", from date, " and ", to date, " is " ) ); print( ( whole( to g - from g, -5 ), " days", newline ) ) ODEND
Days between 1902-01-01 and 1968-12-25 is 24465 daysDays between 2019-01-01 and 2019-01-02 is 1 daysDays between 2019-01-02 and 2019-01-01 is -1 daysDays between 2019-01-01 and 2019-03-01 is 59 daysDays between 2020-01-01 and 2020-03-01 is 60 daysDays between 1995-11-21 and 1995-11-21 is 0 daysDays between 2090-01-01 and 2098-12-25 is 3280 days
begin % calculate the number of days between a pair of dates % % based on a translation of the FreeBASIC sample % integer procedure gregorian ( integer value y, m, d ) ; begin integer n, w; n := ( m + 9 ) - ( ( ( m + 9 ) div 12 ) * 12 ); w := y - ( n div 10 ); ( 365 * w ) + ( w div 4 ) - ( w div 100 ) + ( w div 400 ) + ( ( ( n * 306 ) + 5 ) div 10 ) + ( d - 1 ) end gregorian ; integer procedure toInt( string(4) value s ) ; begin integer v; v := 0; for sPos := 0 until 3 do begin string(1) c; c := s( sPos // 1 ); if c not = " " then v := ( v * 10 ) + ( decode( c ) - decode( "0" ) ) end; v end toInt ; procedure testGregorian ( string(10) value fromDate, toDate ) ; begin integer fromG, toG; fromG := gregorian( toInt( fromDate( 0 // 4 ) ) , toInt( fromDate( 5 // 2 ) ) , toInt( fromDate( 8 // 2 ) ) ); toG := gregorian( toInt( toDate( 0 // 4 ) ) , toInt( toDate( 5 // 2 ) ) , toInt( toDate( 8 // 2 ) ) ); writeon( s_w := 0, "Days between ", fromDate, " and ", toDate, " is " ); writeon( i_w := 5, s_w := 0, toG - fromG, " days" ); write(); end testGregorian ; testGregorian( "1902-01-01", "1968-12-25" );testGregorian( "2019-01-01", "2019-01-02" ); testGregorian( "2019-01-02", "2019-01-01" );testGregorian( "2019-01-01", "2019-03-01" ); testGregorian( "2020-01-01", "2020-03-01" );testGregorian( "1995-11-21", "1995-11-21" ); testGregorian( "2090-01-01", "2098-12-25" )end.
Days between 1902-01-01 and 1968-12-25 is 24465 daysDays between 2019-01-01 and 2019-01-02 is 1 daysDays between 2019-01-02 and 2019-01-01 is -1 daysDays between 2019-01-01 and 2019-03-01 is 59 daysDays between 2020-01-01 and 2020-03-01 is 60 daysDays between 1995-11-21 and 1995-11-21 is 0 daysDays between 2090-01-01 and 2098-12-25 is 3280 days
ondaysBetweenDates(date1,date2)consideringnumeric strings-- Allows for leading zeros having been omitted.if(date1=date2)thenreturndate1&" and "&date2&" are the same date"endconsidering-- Get the components of each date.setastidtoAppleScript'stext item delimiterssetAppleScript'stext item delimitersto"-"set{y1,m1,d1}todate1'stextitemsset{y2,m2,d2}todate2'stextitemssetAppleScript'stext item delimiterstoastid-- Derive AppleScript date objects.-- The best way to do this generally is to use the 'current date' function to obtain a date object-- and then to set the properties of the result (or of a copy) to the required values.-- The initial setting of the day values to 1 is to prevent overflow due to possibly-- incompatible day and month values during the sequential setting of the properties.-- The integer values set here are automatically coerced from the text values obtained above.tell(current date)toset{itsday,itsyear,itsmonth,itsday,itstime,firstDate}to{1,y1,m1,d1,0,it}copyfirstDatetosecondDatetellsecondDatetoset{itsday,itsyear,itsmonth,itsday}to{1,y2,m2,d2}-- Do the math.setdaysDifferenceto(firstDate-secondDate)divdays-- Format some output.if(daysDifference>0)thenreturndate1&" comes "&daysDifference&" day"&item(((daysDifferenceis1)asinteger)+1)of{"s",""}&¬" after "&date2elsereturndate1&" comes "&-daysDifference&" day"&item(((daysDifferenceis-1)asinteger)+1)of{"s",""}&¬" before "&date2endifenddaysBetweenDatesreturndaysBetweenDates("2020-04-11","2001-01-01")&linefeed&¬daysBetweenDates("2020-04-11","2020-04-12")&linefeed&¬daysBetweenDates("2020-04-11","2020-04-11")
"2020-04-11 comes 7040 days after 2001-01-012020-04-11 comes 1 day before 2020-04-122020-04-11 and 2020-04-11 are the same date"
Or, composing a function from reusable generics, and drawing on NSISO8601DateFormatter:
useAppleScriptversion"2.4"useframework"Foundation"usescriptingadditions-- daysBetween :: String -> String -> IntondaysBetween(iso8601From,iso8601To)setmidnightto"T00:00:00+00:00"((dateFromISO8601(iso8601To&midnight)-¬dateFromISO8601(iso8601From&midnight))/86400)asintegerenddaysBetween-- dateFromISO8601 :: String -> DateondateFromISO8601(isoDateString)setcatocurrent applicationtellca'sNSISO8601DateFormatter'salloc'sinit()setitsformatOptionsto¬(ca'sNSISO8601DateFormatWithInternetDateTimeasinteger)(itsdateFromString:(isoDateString))asdateendtellenddateFromISO8601---------------------------TEST----------------------------onrunscriptteston|λ|(ab)set{a,b}toabsetdeltatodaysBetween(a,b)(a&" -> "&b&" -> "&¬justifyRight(5,space,deltaasstring))&¬pluralize(delta," day")end|λ|endscriptunlines(map(test,{¬{"2020-04-11","2001-01-01"},¬{"2020-04-11","2020-04-12"},¬{"2020-04-11","2020-04-11"},¬{"2019-01-01","2019-09-30"}}))endrun--------------------GENERIC FUNCTIONS ----------------------- Absolute value.-- abs :: Num -> Numonabs(x)if0>xthen-xelsexendifendabs-- justifyRight :: Int -> Char -> String -> StringonjustifyRight(n,cFiller,strText)ifn>lengthofstrTextthentext-nthru-1of((replicate(n,cFiller)astext)&strText)elsestrTextendifendjustifyRight-- map :: (a -> b) -> [a] -> [b]onmap(f,xs)-- The list obtained by applying f-- to each element of xs.tellmReturn(f)setlngtolengthofxssetlstto{}repeatwithifrom1tolngsetendoflstto|λ|(itemiofxs,i,xs)endrepeatreturnlstendtellendmap-- mReturn :: First-class m => (a -> b) -> m (a -> b)onmReturn(f)-- 2nd class handler function lifted into 1st class script wrapper.ifscriptisclassoffthenfelsescriptproperty|λ|:fendscriptendifendmReturn-- pluralize :: Int -> String -> Stringonpluralize(n,s)setmtoabs(n)if0=mor2≤mthens&"s"elsesendifendpluralize-- replicate :: Int -> String -> Stringonreplicate(n,s)setoutto""ifn<1thenreturnoutsetdbltosrepeatwhile(n>1)if(nmod2)>0thensetouttoout&dblsetnto(ndiv2)setdblto(dbl&dbl)endrepeatreturnout&dblendreplicate-- unlines :: [String] -> Stringonunlines(xs)-- A single string formed by the intercalation-- of a list of strings with the newline character.set{dlm,mytext item delimiters}to¬{mytext item delimiters,linefeed}setstrtoxsastextsetmytext item delimiterstodlmstrendunlines
2020-04-11 -> 2001-01-01 -> -7040 days2020-04-11 -> 2020-04-12 -> 1 day2020-04-11 -> 2020-04-11 -> 0 days2019-01-01 -> 2019-09-30 -> 272 days
daysBetweenDates:function[startDate,endDate][a:to:date.format:"dd/MM/yyyy"startDateb:to:date.format:"dd/MM/yyyy"endDatereturnabsb\days-a\days]print["days between the two dates:"daysBetweenDates"01/01/2019""19/10/2019"]
days between the two dates: 291
db=(1995-11-21|1995-11-212019-01-01|2019-01-022019-01-02|2019-01-012019-01-01|2019-03-012020-01-01|2020-03-011902-01-01|1968-12-252090-01-01|2098-12-251902-01-01|2098-12-25)fori,lineinStrSplit(db,"`n","`r"){D:=StrSplit(line,"|")result.="Days between "D.1" and "D.2" : "Days_between(D.1,D.2)" Day(s)`n"}MsgBox,262144,,%resultreturnDays_between(D1,D2){D1:=RegExReplace(D1,"\D")D2:=RegExReplace(D2,"\D")EnvSub,D2,%D1,daysreturnD2}
Days between 1995-11-21 and 1995-11-21 : 0 Day(s)Days between 2019-01-01 and 2019-01-02 : 1 Day(s)Days between 2019-01-02 and 2019-01-01 : -1 Day(s)Days between 2019-01-01 and 2019-03-01 : 59 Day(s)Days between 2020-01-01 and 2020-03-01 : 60 Day(s)Days between 1902-01-01 and 1968-12-25 : 24465 Day(s)Days between 2090-01-01 and 2098-12-25 : 3280 Day(s)Days between 1902-01-01 and 2098-12-25 : 71947 Day(s)
# syntax: GAWK -f DAYS_BETWEEN_DATES.AWKBEGIN{regexp="^....-..-..$"# YYYY-MM-DDmain("1969-12-31","1970-01-01","builtin has bad POSIX start date")main("1970-01-01","2038-01-19","builtin has bad POSIX stop date")main("1970-01-01","2019-10-02","format OK")main("1970-01-01","2019/10/02","format NG")main("1995-11-21","1995-11-21","identical dates")main("2019-01-01","2019-01-02","positive date")main("2019-01-02","2019-01-01","negative date")main("2019-01-01","2019-03-01","non-leap year")main("2020-01-01","2020-03-01","leap year")exit(0)}functionmain(date1,date2,comment,d1,d2,diff){printf("\t%s\n",comment)d1=days_builtin(date1)d2=days_builtin(date2)diff=(d1==""||d2=="")?"error":d2-d1printf("builtin %10s to %10s = %s\n",date1,date2,diff)d1=days_generic(date1)d2=days_generic(date2)diff=(d1==""||d2=="")?"error":d2-d1printf("generic %10s to %10s = %s\n",date1,date2,diff)}functiondays_builtin(ymd){# use gawk builtinif(ymd!~regexp){return("")}if(ymd<"1970-01-01"||ymd>"2038-01-18"){return("")}# outside POSIX rangegsub(/-/," ",ymd)return(int(mktime(sprintf("%s 0 0 0",ymd))/(60*60*24)))}functiondays_generic(ymd,d,m,y,result){# use Python formulaif(ymd!~regexp){return("")}y=substr(ymd,1,4)m=substr(ymd,6,2)d=substr(ymd,9,2)m=(m+9)%12y=int(y-int(m/10))result=365*y+int(y/4)-int(y/100)+int(y/400)+int((m*306+5)/10)+(d-1)return(result)}
builtin has bad POSIX start datebuiltin 1969-12-31 to 1970-01-01 = errorgeneric 1969-12-31 to 1970-01-01 = 1 builtin has bad POSIX stop datebuiltin 1970-01-01 to 2038-01-19 = errorgeneric 1970-01-01 to 2038-01-19 = 24855 format OKbuiltin 1970-01-01 to 2019-10-02 = 18171generic 1970-01-01 to 2019-10-02 = 18171 format NGbuiltin 1970-01-01 to 2019/10/02 = errorgeneric 1970-01-01 to 2019/10/02 = error identical datesbuiltin 1995-11-21 to 1995-11-21 = 0generic 1995-11-21 to 1995-11-21 = 0 positive datebuiltin 2019-01-01 to 2019-01-02 = 1generic 2019-01-01 to 2019-01-02 = 1 negative datebuiltin 2019-01-02 to 2019-01-01 = -1generic 2019-01-02 to 2019-01-01 = -1 non-leap yearbuiltin 2019-01-01 to 2019-03-01 = 59generic 2019-01-01 to 2019-03-01 = 59 leap yearbuiltin 2020-01-01 to 2020-03-01 = 60generic 2020-01-01 to 2020-03-01 = 60
10PRINT"Elapsed days from one date to another."20PRINT"Enter dates in YYYY-MM-DD format"30PRINT40INPUT"First Date : ";D$50GOSUB16060DATE1=DAYNUM70INPUT"Second Date : ";D$80GOSUB16090DATE2=DAYNUM100DAYS=DATE2-DATE1110PRINT"Elapsed Days = ";DAYS120INPUT"Do another (y/n)";MSG$130IFMSG$="Y"ORMSG$="y"THENGOTO30140END150REM--Parseandcheckforobviousblunders160Y=VAL(MID$(D$,1,4))170M=VAL(MID$(D$,6,2))180D=VAL(MID$(D$,9,2))190IFM<1ORM>12ORD<1ORD>31THENOK=0ELSEOK=-1200IFOKTHEN250210PRINTCHR$(7);' make beep sound220INPUT"Bad date -- try again:";D$230GOTO160240REM--Computenumericdate250DAYNUM=365*Y+D+31*(M-1)260IFM>=3THENDAYNUM=DAYNUM-INT(.4*M+2.3)ELSEY=Y-1270DAYNUM=DAYNUM+INT(Y/4)-INT(Y/100)+INT(Y/400)+1280RETURN
The dates are taken from the Delphi example
Elapsed days from one date to another.Enter dates in YYYY-MM-DD formatFirst date : 1970-01-01Second date : 2019-10-18Elapsed days = 18187Do another (y/n) ? n
#define _XOPEN_SOURCE#include<stdio.h>#include<stdlib.h>#include<string.h>#include<time.h>intmain(void){charbuf[64];structtmtp;char*p;time_tt1,t2,diff;memset(buf,0,sizeof(buf));memset(&tp,0,sizeof(tp));/* read the first date */printf("Enter the first date (yyyy-mm-dd): ");fflush(stdout);p=fgets(buf,sizeof(buf),stdin);if(p==NULL){fprintf(stderr,"No input detected\n");returnEXIT_FAILURE;}p=strptime(buf,"%Y-%m-%d",&tp);if(p==NULL){fprintf(stderr,"Unable to parse time\n");returnEXIT_FAILURE;}t1=mktime(&tp);/* read the second date */printf("Enter the second date (yyyy-mm-dd): ");p=fgets(buf,sizeof(buf),stdin);if(p==NULL){fprintf(stderr,"No input detected\n");returnEXIT_FAILURE;}p=strptime(buf,"%Y-%m-%d",&tp);if(p==NULL){fprintf(stderr,"Unable to parse time\n");returnEXIT_FAILURE;}t2=mktime(&tp);/* work out the difference in days */if(t2>t1)diff=t2-t1;elsediff=t1-t2;printf("%ld days difference\n",diff/(60*60*24));returnEXIT_SUCCESS;}
Enter the first date (yyyy-mm-dd): 2012-02-01Enter the second date (yyyy-mm-dd): 2012-03-0129 days difference
Thedate namespace is taken from bqn-libs.DBw is the final function which calculates the proper difference between two date strings.
DivMod←⌊∘÷˜⋈|date←{o←719469y←365.25dur←⟨(100×y)-0.75,y,30.6⟩off←⟨o-0.25,0.75,0.41⟩From⇐{y‿m‿d←𝕩f←0>m-↩3(d-o)+´⌊off+⌾(¯1⊸⊑)dur×(100DivMody-f)∾⟨m+12×f⟩}To⇐{t←𝕩c‿y‿m←dur{d‿m←𝕨DivMod𝕩+t⋄t↩⌊m⋄d}¨offm-↩12×10≤m⟨(100×c)+y+m<0,3+m,1+t⟩}}Split←(⊢-˜+`׬)∘=⊔⊢ToI←10⊸×⊸+˜´∘⌽-⟜'0'S2D←ToI¨'-'⊸SplitDBw←-○(date.FromS2D)
"2019-09-30" DBw "2019-01-01"272
#include<chrono>#include<iostream>intmain(){std::chrono::year_month_daydate1{};std::chrono::year_month_daydate2{};std::chrono::from_stream(std::cin,"%Y-%m-%d\n",date1);std::chrono::from_stream(std::cin,"%Y-%m-%d\n",date2);if(std::cin.fail()){std::cout<<"Dates are invalid.\n";}else{std::cout<<"Days difference : "<<(static_cast<std::chrono::sys_days>(date2)-static_cast<std::chrono::sys_days>(date1)).count();}}
2019-01-012019-12-02
Days difference : 335
#include<cstdlib>#include<iostream>#include<boost/date_time/gregorian/gregorian.hpp>intmain(intargc,char**argv){usingnamespaceboost::gregorian;if(argc!=3){std::cerr<<"usage: "<<argv[0]<<" start-date end-date\n";returnEXIT_FAILURE;}try{datestart_date(from_simple_string(argv[1]));dateend_date(from_simple_string(argv[2]));std::cout<<end_date-start_date<<'\n';}catch(conststd::exception&ex){std::cerr<<ex.what()<<'\n';returnEXIT_FAILURE;}returnEXIT_SUCCESS;}
./days_between_dates 2020-01-01 2020-09-06249
usingSystem;usingSystem.Globalization;publicclassProgram{publicstaticvoidMain()=>WriteLine(DateDiff("1970-01-01","2019-10-18"));publicstaticintDateDiff(stringd1,stringd2){vara=DateTime.ParseExact(d1,"yyyy-MM-dd",CultureInfo.InvariantCulture);varb=DateTime.ParseExact(d2,"yyyy-MM-dd",CultureInfo.InvariantCulture);return(int)(b-a).TotalDays;}}
18187
COBOL *> days-between *> Tectonics: cobc -xj days-between.cobidentificationdivision.program-id.days-between.proceduredivision.computetally=functioninteger-of-formatted-date('YYYY-MM-DD','2019-11-24')-functioninteger-of-formatted-date('YYYY-MM-DD','2000-01-01')displaytallycomputetally=functioninteger-of-formatted-date('YYYYMMDD','20191124')-functioninteger-of-formatted-date('YYYYMMDD','20000101')displaytallygoback.endprogramdays-between.
prompt$ cobc -xj days-between-dates.cob0726707267
100REM ===============================110REM DAYS BETWEEN 2 DATES120REM130REM CONVERT FROM TEXT TO PRG140REM USING C64LIST.EXE V3.5150REM COMMAND LINE UTILITY ON WINDOWS160REM170REM V1, 2021-10-09, ALVALONGO180REM ===============================190REM200REM INSPIRED BY THE PYTHON VERSION210REM OF THE ALGORITHM220REM AND THE DISCUSSION AT230REM HTTPS://STACKOVERFLOW.COM/QUESTIONS/12862226240REM /THE-IMPLEMENTATION-OF-CALCULATING-THE-NUMBER-OF-DAYS-BETWEEN-2-DATES250REM ===============================260:1000REM INIT ============================1010PRINTCHR$(147);:REMCLEARSCREEN1020PRINTCHR$(5);:REMINKWHITECOLOR1030POKE53280,3:REMBORDERCOLORCYAN1040POKE53281,14:REMBACKGROUNDCOLORBLUE1050:1100REM MAIN ==========================1110PRINT" DAYS BETWEEN 2 DATES"1120PRINT1130INPUT"FIRST DATE, YEAR";Y11140INPUT"MONTH=";M11150INPUT"DAY =";D11160INPUT"SECOND DATE, YEAR";Y21170INPUT"MONTH=";M21180INPUT"DAY =";D21190Y=Y1:M=M1:D=D1:GOSUB9000:G1=G1200Y=Y2:M=M2:D=D2:GOSUB9000:G2=G1210DI=ABS(G2-G1)1220PRINT"DAYS=";DI1230GETK$:IFK$=""THEN12301240PRINT1250GOTO11201260END1270:9000REM GREGORIAN ======================9010REM TRANSFORM A DATE INTO A DAY NUMBER IN THE GREGORIAN CALENDAR9020REM INPUT PARAMETERS: Y IS YEAR9030REM M IS MONTH9040REM D IS DAY9050N=(M+9)-INT((M+9)/12)*129060W=Y-INT(N/10)9070G=365*W+INT(W/4)-INT(W/100)+INT(W/400)9080G=G+INT((N*306+5)/10)+(D-1)9090RETURN
date1=Time.parse_utc("2025-01-01","%F")date2=Time.parse_utc("2025-11-18","%F")print(date2-date1).days," days between ",date1.to_s("%F")," and ",date2.to_s("%F")puts
321 days between 2025-01-01 and 2025-11-18
importstd.datetime.date;importstd.stdio;voidmain(){autofromDate=Date.fromISOExtString("2019-01-01");autotoDate=Date.fromISOExtString("2019-10-07");autodiff=toDate-fromDate;writeln("Number of days between ",fromDate," and ",toDate,": ",diff.total!"days");}
Number of days between 2019-Jan-01 and 2019-Oct-07: 279
programDays_between_dates;{$APPTYPE CONSOLE}usesSystem.SysUtils;functionCreateFormat(fmt:string;Delimiter:Char):TFormatSettings;beginResult:=TFormatSettings.Create();withResultdobeginDateSeparator:=Delimiter;ShortDateFormat:=fmt;end;end;functionDaysBetween(Date1,Date2:string):Integer;vardt1,dt2:TDateTime;fmt:TFormatSettings;beginfmt:=CreateFormat('yyyy-mm-dd','-');dt1:=StrToDate(Date1,fmt);dt2:=StrToDate(Date2,fmt);Result:=Trunc(dt2-dt1);end;beginWriteln(DaysBetween('1970-01-01','2019-10-18'));readln;end.
18187
func days d$ . y = number substr d$ 1 4 m = number substr d$ 6 2 d = number substr d$ 9 2 m = (m + 9) mod 12 y = y - m div 10 r = 365 * y + y div 4 - y div 100 + y div 400 + (m * 306 + 5) div 10 + (d - 1) return r.d$[][] = [ [ "1995-11-21" "1995-11-21" ] [ "2019-01-01" "2019-01-02" ] [ "2019-01-02" "2019-01-01" ] [ "2019-01-01" "2019-03-01" ] [ "2020-01-01" "2020-03-01" ] [ "1902-01-01" "1968-12-25" ] [ "2090-01-01" "2098-12-25" ] ]for i to len d$[][] print d$[i][1] & " " & d$[i][2] & " -> " & days d$[i][2] - days d$[i][1].
1995-11-21 1995-11-21 -> 02019-01-01 2019-01-02 -> 12019-01-02 2019-01-01 -> -12019-01-01 2019-03-01 -> 592020-01-01 2020-03-01 -> 601902-01-01 1968-12-25 -> 244652090-01-01 2098-12-25 -> 3280
-module(daysbetween).-export([between/2,dateToInts/2]).% Return Year or Month or Date from datestringdateToInts(String,POS)->list_to_integer(lists:nth(POS,string:tokens(String,"-"))).% Alternative form of above% dateToInts(String,POS) ->% list_to_integer( lists:nth( POS, re:split(String ,"-", [{return,list},trim]) ) ).% Return the number of days between dates formatted "2019-09-30"between(DateOne,DateTwo)->L=[1,2,3],[Y1,M1,D1]=[dateToInts(DateOne,X)||X<-L],[Y2,M2,D2]=[dateToInts(DateTwo,X)||X<-L],GregOne=calendar:date_to_gregorian_days(Y1,M1,D1),GregTwo=calendar:date_to_gregorian_days(Y2,M2,D2),GregTwo-GregOne.
erlang shell:
30> c(daysbetween).c(daysbetween).{ok,daysbetween}31> daysbetween:between("2019-01-01", "2019-09-30").daysbetween:between("2019-01-01", "2019-09-30").272Excel dates are numbers counting days since the start of January 1900, and arithmetic operations can be applied to them directly.
(Unless entered as strings, they differ from other numbers only in the display format applied to the containing cell).
The lambda expression below maps over an array of date strings, defining a new array of the differences, in units of one day, between today's date and those earlier dates.
(SeeLAMBDA: The ultimate Excel worksheet function)
The formula in cell B2 defines the array of day counts which populate the rangeB2:B5
| fx | =LAMBDA(dateString, TODAY() - DATEVALUE(dateString) )(C2#) | ||||
|---|---|---|---|---|---|
| A | B | C | D | ||
| 1 | Difference in days | Earlier date | Today | ||
| 2 | 39020 | 1914-07-28 | 2021-05-27 | ||
| 3 | 37088 | 1919-11-11 | |||
| 4 | 29916 | 1939-07-01 | |||
| 5 | 27661 | 1945-09-02 | |||
Alternatively, we can express the same mapping over the wholeC2# array by directly writing:
| fx | = TODAY() - DATEVALUE(C2#) | ||||
|---|---|---|---|---|---|
| A | B | C | D | ||
| 1 | Difference in days | Earlier date | Today | ||
| 2 | 39020 | 1914-07-28 | 2021-05-27 | ||
| 3 | 37088 | 1919-11-11 | |||
| 4 | 29916 | 1939-07-01 | |||
| 5 | 27661 | 1945-09-02 | |||
// Days between dates: Nigel Galloway. June 3rd., 2021letn,g=System.DateTime.Parse("1792-9-22"),System.DateTime.Parse("1805-12-31")printfn"There are %d days between %d-%d-%d and %d-%d-%d"(g-n).Daysn.Yearn.Monthn.Dayg.Yearg.Monthg.Day
There are 4847 days between 1792-9-22 and 1805-12-31
Factor supports the addition and subtraction of timestamps and durations with thetime+ andtime- words.
USING:calendarcalendar.parserkernelmathprettyprint;:days-between(ymd-strymd-str--n)[ymd>timestamp]bi@time-duration>daysabs;"2019-01-01""2019-09-30"days-between."2016-01-01""2016-09-30"days-between.! leap year
272273
DimSharedAsIntegerM,Y,DDimAsIntegerY1,M1,D1,Y2,M2,D2,G1,G2DimAsStringDaysBetween(7,2)={{"1902-01-01","1968-12-25"},_{"2019-01-01","2019-01-02"},{"2019-01-02","2019-01-01"},_{"2019-01-01","2019-03-01"},{"2020-01-01","2020-03-01"},_{"1995-11-21","1995-11-21"},{"2090-01-01","2098-12-25"}}FunctionGregorian()AsIntegerDimAsIntegerN=(M+9)-Int((M+9)/12)*12DimAsIntegerW=Y-Int(N/10)DimAsIntegerG=365*W+Int(W/4)-Int(W/100)+Int(W/400)G+=Int((N*306+5)/10)+(D-1)ReturnGEndFunctionFornAsInteger=0ToUbound(DaysBetween)-1Y1=Val(Left(DaysBetween(n,0),4))M1=Val(Mid(DaysBetween(n,0),6,2))D1=Val(Right(DaysBetween(n,0),2))Y2=Val(Mid(DaysBetween(n,1),1,4))M2=Val(Mid(DaysBetween(n,1),6,2))D2=Val(Mid(DaysBetween(n,1),9,2))Y=Y1:M=M1:D=D1:G1=GregorianY=Y2:M=M2:D=D2:G2=GregorianPrint"Days between ";DaysBetween(n,0);" and ";DaysBetween(n,1);" is ";PrintUsing"##### days";(G2-G1)NextnSleep
Days between 1902-01-01 and 1968-12-25 is 24465 daysDays between 2019-01-01 and 2019-01-02 is 1 daysDays between 2019-01-02 and 2019-01-01 is -1 daysDays between 2019-01-01 and 2019-03-01 is 59 daysDays between 2020-01-01 and 2020-03-01 is 60 daysDays between 1995-11-21 and 1995-11-21 is 0 daysDays between 2090-01-01 and 2098-12-25 is 3280 days
Frink handles dates and intervals between dates robustly, including time zones. The sample below could useminutes orseconds instead ofdays.
Frink can even track leap seconds as they are added to the calendar if desired. The coded1-d2 in the sample below could be replaced bysubtractLeap[d1,d2] to obtain exact counts of seconds between dates.
See Frink'sDate/Time Handling documentation to see how easy it is to work with dates, times, timezones, calendrical systems, and even leap seconds correctly and easily.
d1 = # 2020-12-25 #d2 = # 2020-12-06 #println[d1-d2 -> days]
19
Fōrmulæ programs are not textual, visualization/edition of programs is done showing/manipulating structures but not text. Moreover, there can be multiple visual representations of the same program. Even though it is possible to have textual representation —i.e. XML, JSON— they are intended for storage and transfer purposes more than visualization and edition.
Programs in Fōrmulæ are created/edited online in itswebsite.
Inthis page you can see and run the program(s) related to this task and their results. You can also change either the programs or the parameters they are called with, for experimentation, but remember that these programs were created with the main purpose of showing a clear solution of the task, and they generally lack any kind of validation.
Solution
Note. For this script, the time zone is intentionally set to America/Los_Angeles, because it observesdaylight saving time, It is necesary to solve this exercise.
Provided that the ToNumber expression applied to a time expression reduces to the number of milliseconds of such that time from theepoch:
The solution seems easy, calculating the difference between two times (in milliseconds), and dividing by 86,4000,000 (number of milliseconds in a day):
However, it does not work if one time is in daylight saving time, and the other one is in standard time:
Solution 1
The first solution consists in simply rounding the result to the nearest integer:
Solution 2
The expression GetTimeZoneOffset reduces to the offset (in minutes) of the given time.
The solution consist in taking this difference in account.
So, the function that works correctly is:
Test cases
Notice that it works even for fractions of days:
packagemainimport("fmt""log""time")constlayout="2006-01-02"// template for time.Parse// Parameters assumed to be in YYYY-MM-DD format.funcdaysBetween(date1,date2string)int{t1,err:=time.Parse(layout,date1)check(err)t2,err:=time.Parse(layout,date2)check(err)days:=int(t1.Sub(t2).Hours()/24)ifdays<0{days=-days}returndays}funccheck(errerror){iferr!=nil{log.Fatal(err)}}funcmain(){date1,date2:="2019-01-01","2019-09-30"days:=daysBetween(date1,date2)fmt.Printf("There are %d days between %s and %s\n",days,date1,date2)date1,date2="2015-12-31","2016-09-30"days=daysBetween(date1,date2)fmt.Printf("There are %d days between %s and %s\n",days,date1,date2)}
There are 272 days between 2019-01-01 and 2019-09-30There are 274 days between 2015-12-31 and 2016-09-30
%include inflator/stringcostumes "assets/blank.svg";# convert to julian date from gregorian# https://en.wikipedia.org/wiki/Julian_day#Converting_Gregorian_calendar_date_to_Julian_day_numberfunc julian(y, m, d) { return (1461 * ($y + 4800 + ($m-14)/12) - 3 * ($y + 4900 + ($m-14)/12)/100) / 4 + 367/12 * ($m - 2 - ($m-14)) + $d - 32075;}func diff(one, two) { split $one, "-"; local y1 = split[1]; local m1 = split[2]; local d1 = split[3]; split $two, "-"; local y2 = split[1]; local m2 = split[2]; local d2 = split[3]; # goboscript does not need to cast strings to integers local year2 = julian(y2, m2, d2); local year1 = julian(y1, m1, d1); return floor(year2 - year1);}onflag {main;}proc main { ask "one"; one = answer(); ask "two"; two = answer(); log diff(one, two);}Args: ['2019-01-01', '2019-09-30']Say: 'one'>> '2019-01-01'Say: 'two'>> '2019-09-30'Log: 272Exited with code 0
importjava.time.LocalDatedeffromDate=LocalDate.parse("2019-01-01")deftoDate=LocalDate.parse("2019-10-19")defdiff=fromDate-toDateprintln"Number of days between ${fromDate} and ${toDate}: ${diff}"
Number of days between 2019-01-01 and 2019-10-19: 291
importData.Time(Day)importData.Time.Calendar(diffDays)importData.Time.Format(parseTimeM,defaultTimeLocale)main=doputStrLn$task"2019-01-01""2019-09-30"putStrLn$task"2015-12-31""2016-09-30"task::String->String->Stringtaskxsys="There are "++(show$betweenDaysxsys)++" days between "++xs++" and "++ys++"."betweenDays::String->String->IntegerbetweenDaysdate1date2=go(stringToDaydate1)(stringToDaydate2)wherego(Justx)(Justy)=diffDaysyxgoNothing_=error"Exception: Bad format first date"go_Nothing=error"Exception: Bad format second date"stringToDay::String->MaybeDaystringToDaydate=parseTimeMTruedefaultTimeLocale"%Y-%-m-%-d"date
There are 272 days between 2019-01-01 and 2019-09-30.There are 274 days between 2015-12-31 and 2016-09-30.
Or, composing rather than raising errors:
importData.Time(Day)importData.Time.Calendar(diffDays)importData.Time.Format(defaultTimeLocale,parseTimeM)-------------------- DAYS BETWEEN DATES ------------------daysBetween::String->String->MaybeIntegerdaysBetweens1s2=dayFromStrings2>>=\d2->diffDaysd2<$>dayFromStrings1dayFromString::String->MaybeDaydayFromString=parseTimeMTruedefaultTimeLocale"%Y-%-m-%-d"--------------------------- TEST -------------------------main::IO()main=mapM_(putStrLn.uncurryshowDateDiff)[("2019-01-01","2019-09-30"),("2015-12-31","2016-09-30")]showDateDiff::String->String->StringshowDateDiffs1s2=maybe(unlines["Unparseable as date string pair:",s1,s2])(\n->concat["There are ",shown," days between ",s1," and ",s2,"."])$daysBetweens1s2
There are 272 days between 2019-01-01 and 2019-09-30.There are 274 days between 2015-12-31 and 2016-09-30.
require'~addons/types/datetime/datetime.ijs' 2021 03 16 daysDiff 1960 05 0422231 vectorize=: [: evaluate hyphen_to_space hyphen_to_space=: (=&'-')`(,:&' ')} evaluate=: ". but_first=: & '2021-03-16' daysDiff but_first vectorize '1960-05-04'22231
importjava.time.LocalDate;importjava.time.temporal.ChronoUnit;publicclassDaysBetweenDates{publicstaticvoidmain(String[]args){LocalDatefromDate=LocalDate.parse("2019-01-01");LocalDatetoDate=LocalDate.parse("2019-10-19");longdiff=ChronoUnit.DAYS.between(fromDate,toDate);System.out.printf("Number of days between %s and %s: %d\n",fromDate,toDate,diff);}}
Number of days between 2019-01-01 and 2019-10-19: 291
consttimeRatio=1000*60*60*24;varfloor=Math.floor,abs=Math.abs;vardaysBetween=(d1,d2)=>floor(abs(newDate(d1)-newDate(d2))/timeRatio);console.log('Days between 2021-10-27 and 2020-03-03: %s',daysBetween('2021-10-27','2020-03-03'));
Days between 2021-10-27 and 2020-03-03: 603
Works with gojq, the Go implementation of jq
Two solutions are provided: the first uses jq's built-ins and is very brief.The second starts from first principles,and is of potential interest because of the various generic functionsthat are provided. The output is the same in both cases.
def days_between(yyyymmddBefore; yyyymmddAfter): (yyyymmddBefore | strptime("%Y-%m-%d") | mktime) as $before | (yyyymmddAfter | strptime("%Y-%m-%d") | mktime) as $after # leap seconds are always inserted | (($after - $before) / (24*60*60) | floor) ;def task: def prolog: "In the following, if the dates are not the same,", "the \"from\" date is included in the count of days, but the \"to\" date is not.\n", "If the first date is later than the second date, the count of days is negated."; def dates: ["1995-11-21", "1995-11-21"], ["2019-01-01", "2019-01-02"], ["2019-01-02", "2019-01-01"], ["2019-01-01", "2019-03-01"], ["2020-01-01", "2020-03-01"], ["1902-01-01", "1968-12-25"], ["2090-01-01", "2098-12-25"], ["1902-01-01", "2098-12-25"], ["1970-01-01", "2019-10-18"], ["2019-03-29", "2029-03-29"], ["2020-02-29", "2020-03-01"] ; prolog, (dates | "The number of days from \(.[0]) until \(.[1]) is \(days_between(.[0]; .[1] ))") ;taskIn the following, if the dates are not the same,the "from" date is included in the count of days, but the "to" date is not.If the first date is later than the second date, the count of days is negated.The number of days from 1995-11-21 until 1995-11-21 is 0The number of days from 2019-01-01 until 2019-01-02 is 1The number of days from 2019-01-02 until 2019-01-01 is -1The number of days from 2019-01-01 until 2019-03-01 is 59The number of days from 2020-01-01 until 2020-03-01 is 60The number of days from 1902-01-01 until 1968-12-25 is 24465The number of days from 2090-01-01 until 2098-12-25 is 3280The number of days from 1902-01-01 until 2098-12-25 is 71947The number of days from 1970-01-01 until 2019-10-18 is 18187The number of days from 2019-03-29 until 2029-03-29 is 3653The number of days from 2020-02-29 until 2020-03-01 is 1
Adapted fromWren
# In general, dates should be valid Julian dates on or after Jan 1, 0001, but# for the most part, this is not checked, in part because some# computations based on ostensibly invalid dates do produce useful# results, e.g. days(2000; 1; 1) computes the number of days from Jan 1, 0001# up to and including Jan 1, 2000 whereas days(2000; 1; 0) excludes Jan 1, 2000.# Output: the number of days from and including Jan 1, 0001,# up to but excluding Jan 1 in the year $y for $y >= 1def days_before: if . < 1 then "The input to days_before should be a positive integer, not \(.)"|error else (. - 1 | floor) as $y | $y*365 + (($y/4)|floor) - (($y/100)|floor) + (($y/400)|floor) end;def isLeapYear: .%4 == 0 and (.%100 != 0 or .%400 == 0);# The day of the year (Jan 1 is 1)def day_of_year($y; $m; $d): def diy: [0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334, 365]; def diy2: [0, 31, 60, 91, 121, 152, 182, 213, 244, 274, 305, 335, 366]; $d + if ($y|isLeapYear) then diy2[$m-1] else diy[$m-1] end;# Output: the number of days from Jan 1, 0001 to the specified date, inclusive.def days($y; $m; $d): ($y | days_before) + day_of_year($y; $m; $d);# Output: the signed difference in the "days" values of the two dates.# If the first specified date is later than the second specified date,# then the result is the number of days from and including the earlier date,# up to but excluding the later date.def days_between(Year; Month; Day; laterYear; laterMonth; laterDay): days(laterYear; laterMonth; laterDay) - days(Year; Month; Day);# Dates in yyyy-mm-dd format or as a numeric array [y,m,d]def days_between(date; later): def toa: if type == "string" then split("-") | map(tonumber) else . end; (later | toa) as $later | (date | toa) as $date | days_between($date[0]; $date[1]; $date[2]; $later[0]; $later[1]; $later[2]);The Tasks
As above.
Same as above.
usingDates@showDay(DateTime("2019-09-30")-DateTime("2019-01-01"))@showDay(DateTime("2019-03-01")-DateTime("2019-02-01"))@showDay(DateTime("2020-03-01")-DateTime("2020-02-01"))@showDay(DateTime("2029-03-29")-DateTime("2019-03-29"))
Day(DateTime("2019-09-30") - DateTime("2019-01-01")) = 272 daysDay(DateTime("2019-03-01") - DateTime("2019-02-01")) = 28 daysDay(DateTime("2020-03-01") - DateTime("2020-02-01")) = 29 daysDay(DateTime("2029-03-29") - DateTime("2019-03-29")) = 3653 daysimportjava.time.LocalDateimportjava.time.temporal.ChronoUnitfunmain(){valfromDate=LocalDate.parse("2019-01-01")valtoDate=LocalDate.parse("2019-10-19")valdiff=ChronoUnit.DAYS.between(fromDate,toDate)println("Number of days between $fromDate and $toDate: $diff")}
Number of days between 2019-01-01 and 2019-10-19: 291
This uses os.difftime to compare two Epoch times. Not to be used with dates before 1970.
SECONDS_IN_A_DAY=60*60*24-- Convert date string as YYYY-MM-DD to Epoch time.functionparseDate(str)localy,m,d=string.match(str,"(%d+)-(%d+)-(%d+)")returnos.time({year=y,month=m,day=d})end-- Main procedureio.write("Enter date 1: ")locald1=parseDate(io.read())io.write("Enter date 2: ")locald2=parseDate(io.read())localdiff=math.ceil(os.difftime(d2,d1)/SECONDS_IN_A_DAY)print("There are "..diff.." days between these dates.")
Enter date 1: 1970-01-01Enter date 2: 2019-10-02There are 18171 days between these dates.
Version 12 has date type, so we can handle easy dates.
MODULEDays_between_dates{DATEa="2019-01-01",b="2019-09-30"LONGz=b-a//Usethesystemdefaulttodisplaydates(DD/MM/YYYY)PRINT"Days from "+a+" to "+b+" = "+z//usinglocale1033todisplaydates(MM/DD/YYYY)PRINT"Days from "+DATE$(a,1033,"SHORT DATE")+" to "+DATE$(b,1033,"SHORT DATE")+" = "+z}Days_between_dates
Days from 1/1/2019 to 30/9/2019 = 272Days from 1/1/2019 to 9/30/2019 = 272
DateDifference["2020-01-01","2020-03-01"]DateDifference["2021-01-01","2021-03-01"]
Quantity[60, "Days"]Quantity[59, "Days"]
importtimesprocdaysBetween(date1,date2:string):int64=constFmt=initTimeFormat("yyyy-MM-dd")(date2.parse(Fmt,utc())-date1.parse(Fmt,utc())).inDaysconstDates=[("1995-11-21","1995-11-21"),("2019-01-01","2019-01-02"),("2019-01-02","2019-01-01"),("2019-01-01","2019-03-01"),("2020-01-01","2020-03-01"),("1902-01-01","1968-12-25"),("2090-01-01","2098-12-25")]for(date1,date2)inDates:echo"Days between ",date1," and ",date2,": ",daysBetween(date1,date2)
Days between 1995-11-21 and 1995-11-21: 0Days between 2019-01-01 and 2019-01-02: 1Days between 2019-01-02 and 2019-01-01: -1Days between 2019-01-01 and 2019-03-01: 59Days between 2020-01-01 and 2020-03-01: 60Days between 1902-01-01 and 1968-12-25: 24465Days between 2090-01-01 and 2098-12-25: 3280
ProgramDaysBetweenDates;{$mode ObjFPC}{$H+}Usesdateutils,strutils;TypeTarr=arrayofarrayOfstring;Constlst:Tarr=(('1902-01-01','1968-12-25'),('2019-01-01','2019-01-02'),('2019-01-02','2019-01-01'),('2019-01-01','2019-03-01'),('2020-01-01','2020-03-01'),('1995-11-21','1995-11-21'),('2090-01-01','2098-12-25'),('1967-02-23','2024-03-21'));Functionstrtodate(str:String):tdatetime;Beginresult:=ScanDateTime('YYYYMMDD',DelChars(str,'-'));End;Vararr:arrayofstring;DaysBetw:integer;BeginForarrInlstDoBeginDaysBetw:=DaysBetween(strtodate(arr[0]),strtodate(arr[1]));writeln(arr[0],' - ',arr[1],' -> ',DaysBetw);End;End.
1902-01-01 - 1968-12-25 -> 244652019-01-01 - 2019-01-02 -> 12019-01-02 - 2019-01-01 -> 12019-01-01 - 2019-03-01 -> 592020-01-01 - 2020-03-01 -> 601995-11-21 - 1995-11-21 -> 02090-01-01 - 2098-12-25 -> 32801967-02-23 - 2024-03-21 -> 20846
Would not reinvent this wheel.
usefeature'say';useDate::Calcqw(Delta_Days);sayDelta_Days(2018,7,13,2019,9,13);# triskaidekaphobiasayDelta_Days(1900,1,1,2000,1,1);# a centurysayDelta_Days(2000,1,1,2100,1,1);# another, with one extra leap daysayDelta_Days(2020,1,1,2019,10,1);# backwards in timesayDelta_Days(2019,2,29,2019,3,1);# croaks
4273652436525-92Date::Calc::PP::Delta_Days(): Date::Calc::Delta_Days(): not a valid date at Days_between_dates line 10
withjavascript_semanticsincludebuiltins\timedate.e-- specify as many or as few permitted formats as you like:set_timedate_formats({"YYYY-MM-DD","DD/MM/YYYY","YYYY/MM/DD"})constantSECONDS_TO_DAYS=60*60*24proceduretest(stringd1,d2,desc="")timedatetd1=parse_date_string(d1),td2=parse_date_string(d2)atoms=timedate_diff(td1,td2,DT_DAY),d=s/SECONDS_TO_DAYSstringe=elapsed(s)&descprintf(1,"Days between %s and %s: %d [%s]\n",{d1,d2,d,e})endproceduretest("1969-12-31","1970-01-01")test("1995-11-21","1995-11-21",", same date")test("2019-01-02","2019-01-01",", negative date")test("2019-01-01","2019-03-01",", non-leap year")test("2020-01-01","2020-03-01",", leap year")test("1970-01-01","2019/10/18")test("1970-01-01","18/10/2019")
As shown, timedate_diff() can optionally round to the nearest whole number of days [else omit DT_DAY].
Note that elapsed() assumes all years are exactly 365 days, and in no way takes leap years into consideration(as opposed, of course, to timedate_diff() which handles them flawlessly), not that you sh/c/would ever use the string output of elapsed() in any further calculations anyway.
Days between 1969-12-31 and 1970-01-01: 1 [1 day]Days between 1995-11-21 and 1995-11-21: 0 [0s, same date]Days between 2019-01-02 and 2019-01-01: -1 [minus 1 day, negative date]Days between 2019-01-01 and 2019-03-01: 59 [59 days, non-leap year]Days between 2020-01-01 and 2020-03-01: 60 [60 days, leap year]Days between 1970-01-01 and 2019/10/18: 18187 [49 years, 302 days]Days between 1970-01-01 and 18/10/2019: 18187 [49 years, 302 days]
(de diffDates (A B) (abs (- ($dat A "-") ($dat B "-"))) )(println (diffDates "2019-1-1" "2019-9-30"))(println (diffDates "2015-12-31" "2016-09-30"))
272274
elapsed_days: proc options (main); dcl (date1, date2) float bin, another char(1); put skip list ('Elapsed days calculator'); another = 'Y'; do while ((another = 'Y') | (another = 'y')); put skip list ('First date as YYYY-MM-DD : '); date1 = get_date(); put list ('Second date as YYYY-MM-DD : '); date2 = get_date(); put skip edit ('Elapsed days = ', date2-date1) (a,f(6)); put skip list ('Do another (y/n)? '); get edit (another) (a); end;/** Read a date in YYYY-MM-DD format from the * console and return its serial date equivalent*/get_date: proc returns (float bin); dcl date char(20) varying; dcl (y, m, d) float bin; get edit (date) (a); y = binary(substr(date,1,4)); m = binary(substr(date,6,2)); d = binary(substr(date,9,2)); return (serial_date(y,m,d));end get_date; /** Given a year, month and day in the Gregorian* calendar, return a numeric date which is equal * to the number of days since the start of the* Common era*/serial_date: proc (yr, mo, da) returns (float bin); dcl (yr, mo, da) float bin; dcl n float bin; n = 365 * yr + da + 31 * (mo - 1); if (mo >= 3) then n = n - fixed(0.4 * mo + 2.3); else yr = yr - 1; n = n + fixed(yr/4) - fixed(0.75 * fixed(yr/100) + 1); return (n);end serial_date;end elapsed_days;Test case taken from the Delphi example
Elapsed Date CalculatorFirst date as YYYY-MM-DD : 1970-01-01Second date as YYYY-MM-DD : 2019-10-18Elapsed days = 18187Do another (y/n)? n
... under CP/M (or an emulator)
Note that as the 8080 PL/M compiler only supports 8 and 16 bit unsigned integers, the dates must be at most 65535 days apart.
100H: /* CALCULATE THE NUMBER OF DAYS BETWEEN TWO DATES; BASED ON FREEBASIC */ /* CP/M BDOS SYSTEM CALL AND I/O ROUTINES */ BDOS: PROCEDURE( FN, ARG ); DECLARE FN BYTE, ARG ADDRESS; GOTO 5; END; PR$CHAR: PROCEDURE( C ); DECLARE C BYTE; CALL BDOS( 2, C ); END; PR$STRING: PROCEDURE( S ); DECLARE S ADDRESS; CALL BDOS( 9, S ); END; PR$NL: PROCEDURE; CALL PR$CHAR( 0DH ); CALL PR$CHAR( 0AH ); END; PR$NUMBER: PROCEDURE( N ); /* PRINTS A NUMBER IN THE MINIMUN FIELD WIDTH */ DECLARE N ADDRESS; DECLARE V ADDRESS, N$STR ( 6 )BYTE, W BYTE; V = N; W = LAST( N$STR ); N$STR( W ) = '$'; N$STR( W := W - 1 ) = '0' + ( V MOD 10 ); DO WHILE( ( V := V / 10 ) > 0 ); N$STR( W := W - 1 ) = '0' + ( V MOD 10 ); END; CALL PR$STRING( .N$STR( W ) ); END PR$NUMBER; PR$SIGNED: PROCEDURE( N ); /* PRINTS N AS A SIGNED INTEGER */ DECLARE N ADDRESS; IF N <= 32767 THEN CALL PR$NUMBER( N ); ELSE DO; CALL PR$CHAR( '-' ); CALL PR$NUMBER( - N ); END; END PR$SIGNED ; /* TASK */ /* RETURNS THE GREGORIAN DAY CORRESPONDING TO YYYY/MM/DD */ GREGORIAN: PROCEDURE( YYYY$MM$DD )ADDRESS; DECLARE YYYY$MM$DD ADDRESS; DECLARE DATE BASED YYYY$MM$DD ( 10 )BYTE; DECLARE ( YYYY, MM, DD, N, W ) ADDRESS; DIGIT: PROCEDURE( D )BYTE; DECLARE D BYTE; RETURN D - '0'; END; YYYY = ( DIGIT( DATE( 0 ) ) * 1000 ) + ( DIGIT( DATE( 1 ) ) * 100 ) + ( DIGIT( DATE( 2 ) ) * 10 ) + DIGIT( DATE( 3 ) ); MM = ( DIGIT( DATE( 5 ) ) * 10 ) + DIGIT( DATE( 6 ) ); DD = ( DIGIT( DATE( 8 ) ) * 10 ) + DIGIT( DATE( 9 ) ); N = ( MM + 9 ) - ( ( ( MM + 9 ) / 12 ) * 12 ); W = YYYY - ( N / 10 ); RETURN ( 365 * W ) + ( W / 4 ) - ( W / 100 ) + ( W / 400 ) + ( ( ( N * 306 ) + 5 ) / 10 ) + ( DD - 1 ); END GREGORIAN ; /* SHOWS TTHE DAYS DIFFERENCE BETWEEN FROM$G AND TO$$G */ PR$DAYS$DIFFERENCE: PROCEDURE( FROM$DATE, TO$DATE ); DECLARE ( FROM$DATE, TO$DATE )ADDRESS; CALL PR$STRING( .'DAYS BETWEEN $' );CALL PR$STRING( FROM$DATE ); CALL PR$STRING( .' AND $' );CALL PR$STRING( TO$DATE ); CALL PR$STRING( .' IS $' ); CALL PR$SIGNED( GREGORIAN( TO$DATE ) - GREGORIAN( FROM$DATE ) ); CALL PR$NL; END PR$DAYS$DIFFERENCE ; CALL PR$DAYS$DIFFERENCE( .'1902-01-01$', .'1968-12-25$' ); CALL PR$DAYS$DIFFERENCE( .'2019-01-01$', .'2019-01-02$' ); CALL PR$DAYS$DIFFERENCE( .'2019-01-02$', .'2019-01-01$' ); CALL PR$DAYS$DIFFERENCE( .'2019-01-01$', .'2019-03-01$' ); CALL PR$DAYS$DIFFERENCE( .'2020-01-01$', .'2020-03-01$' ); CALL PR$DAYS$DIFFERENCE( .'1995-11-21$', .'1995-11-21$' ); CALL PR$DAYS$DIFFERENCE( .'2090-01-01$', .'2098-12-25$' );EOF
DAYS BETWEEN 1902-01-01 AND 1968-12-25 IS 24465DAYS BETWEEN 2019-01-01 AND 2019-01-02 IS 1DAYS BETWEEN 2019-01-02 AND 2019-01-01 IS -1DAYS BETWEEN 2019-01-01 AND 2019-03-01 IS 59DAYS BETWEEN 2020-01-01 AND 2020-03-01 IS 60DAYS BETWEEN 1995-11-21 AND 1995-11-21 IS 0DAYS BETWEEN 2090-01-01 AND 2098-12-25 IS 3280
localdate_pairs={{"1995-11-21","1995-11-21"},{"2019-01-01","2019-01-02"},{"2019-01-02","2019-01-01"},{"2019-01-01","2019-03-01"},{"2020-01-01","2020-03-01"},{"1902-01-01","1968-12-25"},{"2090-01-01","2098-12-25"},{"1902-01-01","2098-12-25"},{"1970-01-01","2019-10-18"},{"2019-03-29","2029-03-29"},{"2020-02-29","2020-03-01"}}fordate_pairsasdatesdolocal[y1,m1,d1]=dates[1]:split("-")localt1=os.time({year=y1,month=m1,day=d1})local[y2,m2,d2]=dates[2]:split("-")localt2=os.time({year=y2,month=m2,day=d2})localdays=math.ceil(os.difftime(t2,t1)/86400)print($"Days between {dates[1]} and {dates[2]} = {days}")end
Days between 1995-11-21 and 1995-11-21 = 0Days between 2019-01-01 and 2019-01-02 = 1Days between 2019-01-02 and 2019-01-01 = -1Days between 2019-01-01 and 2019-03-01 = 59Days between 2020-01-01 and 2020-03-01 = 60Days between 1902-01-01 and 1968-12-25 = 24465Days between 2090-01-01 and 2098-12-25 = 3280Days between 1902-01-01 and 2098-12-25 = 71947Days between 1970-01-01 and 2019-10-18 = 18187Days between 2019-03-29 and 2029-03-29 = 3653Days between 2020-02-29 and 2020-03-01 = 1
"""Days between dates. Requires Python >= 3.9.https://rosettacode.org/wiki/Days_between_dates#Python"""defdays(year:int,month:int,day:int)->int:"""Return a count of days between an arbitrary but consistent epoch and the given date. See: https://stackoverflow.com/questions/12862226/the-implementation-of-calculating-the-number-of-days-between-2-dates """# Shift to begin the year in march.month=(month+9)%12year=year-month//10days_since_march_first=(month*306+5)//10return(365*year+year//4-year//100+year//400+days_since_march_first+(day-1))defdiff(one:str,two:str)->int:"""Return the count of days between dates `one` and `two`."""years_one=days(*(int(s)forsinone.split("-")))years_two=days(*(int(s)forsintwo.split("-")))returnyears_two-years_oneif__name__=="__main__":importsysone=sys.argv[1]two=sys.argv[2]print(diff(one,two))
python days-between.py 2019-01-01 2019-09-30272
fromdatetimeimportdatetimedefdays_between_dates(one:str,two:str)->int:"""Return the count of days between dates `one` and `two`."""delta=datetime.strptime(two,"%Y-%m-%d")-datetime.strptime(one,"%Y-%m-%d")returndelta.daysif__name__=="__main__":importsysone=sys.argv[1]two=sys.argv[2]print(days_between_dates(one,two))
'Task'Calculate the number of days between two dates.'Date input should be of the form YYYY-MM-DD.from$ = "2000-05-29"to$ = "2022-05-29"Print NumberOfDays(from$, to$)EndFunction NumberOfDays (from$, to$) NumberOfDays = 0 Dim As Integer Year(1 To 2), Mounth(1 To 2), Day(1 To 2) Dim As Integer NumberD, Index Year(1) = Val(Left$(from$, 4)) Year(2) = Val(Left$(to$, 4)) Mounth(1) = Val(Mid$(from$, 6, 2)) Mounth(2) = Val(Mid$(to$, 6, 2)) Day(1) = Val(Right$(from$, 2)) Day(2) = Val(Right$(to$, 2)) If Year(1) > Year(2) Then Swap Year(1), Year(2) Swap mount(1), mount(2) Swap Day(1), Day(2) End If If Day(1) > Day(2) Then Select Case Mounth(2) - 1 Case 4, 6, 9, 11 Day(2) = Day(2) + 30 Case 1, 3, 5, 7, 8, 10, 12 Day(2) = Day(2) + 31 Case 2 If (Index Mod 4 = 0) Or ((Index Mod 100 = 0) And (Index Mod 400 = 0)) Then Day(2) = Day(2) + 29 Else Day(2) = Day(2) + 28 End Select Mounth(2) = Mounth(2) - 1 If Mounth(2) = 0 Then Year(2) = Year(2) - 1: Mounth(2) = 12 End If NumberD = (Day(2) - Day(1)) + 1 For Index = Mounth(1) To Mounth(2) - 1 Step 1 Select Case Index Case 4, 6, 9, 11 NumberD = NumberD + 30 Case 1, 3, 5, 7, 8, 10, 12 NumberD = NumberD + 31 Case 2 If (Index Mod 4 = 0) Or ((Index Mod 100 = 0) And (Index Mod 400 = 0)) Then NumberD = NumberD + 29 Else NumberD = NumberD + 28 End Select Next For Index = Year(1) To Year(2) - 1 Step 1 If (Index Mod 4 = 0) Or ((Index Mod 100 = 0) And (Index Mod 400 = 0)) Then NumberD = NumberD + 366 Else NumberD = NumberD + 365 Next Index NumberOfDays = NumberDEnd Function
The number of days between two dates is always positive – there is no such thing as -5 days. Strictly, it returns the number of midnights between two dates. As the task stands two consecutive dates are considered to have one day between them, which is a little weird but we know what it means.
[ 0 ] is january ( --> n ) [ 31 ] is february ( --> n ) [ 59 ] is march ( --> n ) [ 90 ] is april ( --> n ) [ 120 ] is may ( --> n ) [ 151 ] is june ( --> n ) [ 181 ] is july ( --> n ) [ 212 ] is august ( --> n ) [ 243 ] is september ( --> n ) [ 273 ] is october ( --> n ) [ 304 ] is november ( --> n ) [ 334 ] is december ( --> n ) [ 1 - dup 4 / over 100 / - swap 400 / + ] is leapcount ( y --> n ) [ dup leapcount swap 365 * + ] is yeardays ( y --> n ) [ dup 400 mod 0 = iff [ drop true ] done dup 100 mod 0 = iff [ drop false ] done 4 mod 0 = ] is leap ( y --> b ) [ do dup yeardays dip [ over february > iff [ leap + ] else drop ] + + ] is daycount ( [dmy] --> n ) [ daycount swap daycount - abs ] is daysbetween ( [dmy] [dmy] --> n )say "Days between 1995-11-21 and 1995-11-21 is "' [ 21 november 1995 ] ' [ 21 november 1995 ] daysbetween echo crsay "Days between 2019-01-01 and 2019-01-02 is "' [ 1 january 2019 ] ' [ 2 january 2019 ] daysbetween echo crsay "Days between 2019-01-02 and 2019-01-01 is "' [ 2 january 2019 ] ' [ 1 january 2019 ] daysbetween echo crsay "Days between 2019-01-01 and 2019-03-01 is "' [ 1 january 2019 ] ' [ 1 march 2019 ] daysbetween echo crsay "Days between 2020-01-01 and 2020-03-01 is "' [ 1 january 2020 ] ' [ 1 march 2020 ] daysbetween echo crsay "Days between 1902-01-01 and 1968-12-25 is "' [ 1 january 1902 ] ' [ 25 december 1968 ] daysbetween echo crsay "Days between 2090-01-01 and 2098-12-25 is "' [ 1 january 2090 ] ' [ 25 december 2098 ] daysbetween echo crsay "Days between 1902-01-01 and 2098-12-25 is "' [ 1 january 1902 ] ' [ 25 december 2098 ] daysbetween echo cr
Days between 1995-11-21 and 1995-11-21 is 0Days between 2019-01-01 and 2019-01-02 is 1Days between 2019-01-02 and 2019-01-01 is 1Days between 2019-01-01 and 2019-03-01 is 59Days between 2020-01-01 and 2020-03-01 is 60Days between 1902-01-01 and 1968-12-25 is 24465Days between 2090-01-01 and 2098-12-25 is 3280Days between 1902-01-01 and 2098-12-25 is 71947
R natively supports date arithmetic. Possible operations are subtracting one date from another (which can produce a negative result), taking a date and adding or subtracting a number of days, and comparing one date to another (>, <, ==, !=, >=, and <= all work).
as.Date("2025-10-04")-as.Date("2025-05-05")as.Date("2025-04-10")-as.Date("2025-05-05")as.Date("2025-10-04")+31
Time difference of 152 daysTime difference of -25 days[1] "2025-11-04"
(formerly Perl 6)Dates are first class objects in Raku and may have arithmetic in days done directly on them.
sayDate.new('2019-09-30') -Date.new('2019-01-01');sayDate.new('2019-03-01') -Date.new('2019-02-01');sayDate.new('2020-03-01') -Date.new('2020-02-01');sayDate.new('2029-03-29') -Date.new('2019-03-29');sayDate.new('2019-01-01') +90;sayDate.new('2020-01-01') +90;sayDate.new('2019-02-29') +30;CATCH {default { .message.say;exit; } };
272282936532019-04-012020-03-31Day out of range. Is: 29, should be in 1..28
Rebol accepts a multitude of lexically recognized date! formats. date! is a builtin datatype. Slashes or dashes, year-month-day, day/month/year, or dd/monthname/year, etc. Math on dates defaults to days.
2019-11-24-2000-01-01;== 72672019-nov-24-01-jan-2000;== 7267</syntaxhighlight=={{header|REXX}}=={{works with|Regina REXX}}===barebonesversion===Programmingnote: the '''B''' ('''B'''ase) anoptionforthe '''date''' BIFwhichindicatestocomputethenumberof<br>dayssincethebeginningoftheGregoriancalendar, and '''I''' whichistheoptionthatindicatesthedateisin<br>the '''ISO''' (InternationalStandardsOrganizationstandard8601:2004) format.<syntaxhighlightlang="rexx">/*REXXprogramcomputesthenumberofdaysbetweentwodatesintheformofYYYY-MM-DD*/parsearg$1$2./*get2arguments(dates)fromtheC.L.*/sayabs(date('B',$1,"I")-date('B',$2,"I"))'daysbetween'$1" and "$2/*stickaforkinit,we'realldone.*/
7214 days between 2019-10-02 and 2000-01-01
This REXX version supports more variations in the date format (allows a single digit month and/or day), as well as
allowing a single asterisk (*) to be used for a date (which signifies that the current date is to be used).
The dates may be specified in the following formats:
, (a comma) indicates today's date * (an asterisk) indicates today's date yyyy-mm-dd whereyyyy may be a 2- or 4-digit year,mm may be a 1- or 2-digit month,dd may be a 1- or 2-digit day of month mm/dd/yyyy (as above) mm/dd (as above), but the current year is assumed dd\mm\yyyy (as above) dd\mm (as above), but the current year is assumed
Commas (,) are inserted into numbers where appropriate.
Also, more informative error messages are generated.
/*REXX program computes the number of days between two dates in the form of YYYY-MM-DD */parsearg$.1$.2_.1..xtra/*obtain two arguments from the C.L. */seps='/-\';yr.=.;mon.=.;dd.=./*define the defaults for both dates. */doa=1for2/*process both of the specified dates. */if$.a==''|$.a=="*"|$.a==','then$.a=date("I")dos=1forlength(seps)/*process a specified date by separator*/sep=substr(seps,s,1)/*obtain one of the supported sep char.*/ifpos(sep,$.a)\==0thencallconv$.a/*parse the date string.*/end/*s*/end/*a*/?.1='1st'?.2='2nd'if_\==''thencallerr"too many arguments specified: "xtrady.=31/*default number of days for all months*/parsevalue30withdy.41dy.61dy.91dy.11/*define 30─day months, Feb. is special*/@notCorr="isn't in a support date format: "/*used for a literal for an error msg. */doj=1for2/*examine both dates for correct format*/if$.j==''thencallerr?.j"date was not specified."iflength(yr.j)==0thencallerr?.j"year"@notCorr'(missing)'ifisDec(yr.j)thencallerr?.j"year"@notCorr'(has a non─decimal digit)'ifyr.j<1|yr.j>9999thencallerr?.j"year"@notCorr'(not in the range 1──►9999)'iflength(mon.j)==0thencallerr?.j"month"@notCorr'(missing)'ifisDec(mon.j)thencallerr?.j"month"@notCorr'(has a non─decimal digit)'ifmon.j<1|mon.j>12thencallerr?.j"month"@notCorr'(not in the range 1──►12)'iflength(dd.j)==0thencallerr?.j"day"@notCorr'(missing)'ifisDec(dd.j)thencallerr?.j"day"@notCorr'(has a non─decimal digit)'mo=mon.jifleapYr(yr.j)thendy.2=29/*Is it a leapyear? Use 29 days for Feb*/elsedy.2=28/*Isn't " " " 28 " " " */ifdd.j<1|dd.j>dy.mothencallerr?.j"day"@notCorr'(day in month is invalid)'yr.j=right(yr.j+0,4,0)/*force YYYY to be four decimal digits.*/mon.j=right(mon.j+0,2,0)/* " MON " " two " " */dd.j=right(dd.j+0,2,0)/* " DD " " " " " */$.j=yr.j'-'mon.j"-"dd.j/*reconstitute a date from above parts.*/end/*j*/between=abs(date('B',$.1,"I")-date('B',$.2,"I"))/* # days between dates.*/parsesource.how./*determine how invoked.*/ifhow='COMMAND'thensaycommas(between)' days between '$.1" and "$.2exitbetween/*stick a fork in it, we're all done. *//*──────────────────────────────────────────────────────────────────────────────────────*/commas:parsearg_;doc_=length(_)-3to1by-3;_=insert(',',_,c_);end;return_err:say;say'***error*** 'arg(1);exit13/*issue an error message (with text) */isDec:returnverify(arg(1),1234567890)\==0/*insure argument is just decimal digs.*/leapYr:arg_;ly=_//4==0;ifly==0thenreturn0;ly=((_//100\==0)|_//400==0);returnlyserDAT:callerr'illegal date format with a separator= ['sep"], date= "@dat/*──────────────────────────────────────────────────────────────────────────────────────*/conv:parsearg@dat/*obtain date that the user specified. */ifsep=='-'thenparsevar@datyr.a"-"mon.a'-'dd.a/* yy-mm-dd */ifsep=='/'thenparsevar@datmon.a"/"dd.a'/'yr.a/* mm/dd/yy */ifsep=='\'thenparsevar@datdd.a"\"mon.a'\'yr.a/* dd\mm\yy */ifyr.a==''thenyr.a=right(date(),4)/*omitted yy*/iflength(yr.a)==2thenyr.a=left(date('S'),2)yr.a/*2 dig yy ?*/ifyr.a==.|mon.a==.|dd.a==.thencallserDAT/*validate. */return
Today (indicated by the asterisk) is 2019-10-2
7,214 days between 2019-10-02 and 2000-01-01
load "stdlib.ring"DaysBetween = [["1995-11-21","1995-11-21"], ["2019-01-01","2019-01-02"], ["2019-01-02","2019-01-01"], ["2019-01-01","2019-03-01"], ["2020-01-01","2020-03-01"], ["1902-01-01","1968-12-25"], ["2090-01-01","2098-12-25"]]for n = 1 to len(DaysBetween) date1 = DaysBetween[n][1] date2 = DaysBetween[n][2] date3 = substr(date1,9,2) + "/" + substr(date1,6,2) + "/" + substr(date1,1,4) date4 = substr(date2,9,2) + "/" + substr(date2,6,2) + "/" + substr(date2,1,4) ? "Days between " + DaysBetween[n][1] + " and " + DaysBetween[n][2] + ": " + diffdays(date4,date3)next
Days between 1995-11-21 and 1995-11-21: 0Days between 2019-01-01 and 2019-01-02: 1Days between 2019-01-02 and 2019-01-01: -1Days between 2019-01-01 and 2019-03-01: 59Days between 2020-01-01 and 2020-03-01: 60Days between 1902-01-01 and 1968-12-25: 0Days between 2090-01-01 and 2098-12-25: 3280
Uses Python formula, in a forced binary calculation mode to avoid 'flooring' instructions
≪ → d m y ≪ m 9 + 12 MOD y OVER #10d / - DUP 365 * OVER #4d / + OVER #100d / - SWAP #400d / + SWAP 306 * 5 + #10d / + d + 1 - B→R ≫ ≫ 'GREGN' STO≪ SWAP 1 2START → date ≪ date 9 10 SUB STR→ date 6 7 SUB STR→ date 1 4 SUB STR→ GREGN SWAP ≫NEXT - ≫'NBDAYS' STO
"1902-01-01" "1968-12-25" NBDAYS"2019-01-02" "2019-01-01" NBDAYS"2019-01-01" "2019-03-01" NBDAYS"2020-01-01" "2020-03-01" NBDAYS
4: 24465 3: -12: 591: 60
require"date"d1,d2=Date.parse("2019-1-1"),Date.parse("2019-10-19")p(d1-d2).to_i# => -291p(d2-d1).to_i# => 291
// [dependencies]// chrono = "0.4"usechrono::NaiveDate;fnmain(){letargs:Vec<String>=std::env::args().collect();ifargs.len()!=3{eprintln!("usage: {} start-date end-date",args[0]);std::process::exit(1);}ifletOk(start_date)=NaiveDate::parse_from_str(&args[1],"%F"){ifletOk(end_date)=NaiveDate::parse_from_str(&args[2],"%F"){letd=end_date.signed_duration_since(start_date);println!("{}",d.num_days());}else{eprintln!("Can't parse end date");std::process::exit(1);}}else{eprintln!("Can't parse start date");std::process::exit(1);}}
days_between_dates 2020-01-01 2020-09-06249
Error checking of entered dates is omitted in order to focuson the stated task but would obviously have to be includedin production code.
commentGivenamonth,day,andyearintheGregoriancalendar,returnanumericdatewhichisequaltothenumberofdayssincethestartoftheCommonera.endfunctionserial_date(da,mo,yr=integer)=realvarn=realn=365*yr+da+31*(mo-1)ifmo>=3thenn=n-int(.4*mo+2.3)elseyr=yr-1n=n+int(yr/4)-int(.75*(int(yr/100)+1))end=ncommentReadadateinYYYY-MM-DDformatfromtheconsoleandreturnitsserialdateequivalent.endfunctionget_date=realvardate=string:20vary,m,d=integerinput2datey=val(mid(date,1,4))m=val(mid(date,6,2))d=val(mid(date,9,2))end=serial_date(d,m,y)rem--mainprogrambeginsherevardate1,date2=realvaranother=charrepeatbeginprint"First date : ";date1=get_dateprint"Second date : ";date2=get_dateprint"Elapsed days = ";date2-date1input"Do another (y/n)";anotherenduntilnotanotherend
Test dates taken from Delphi example
First date : 1970-01-01Second date : 2019-10-18Elapsed days = 18187Do another (y/n)? n
objectDaysBetweenDates{/*Inspired by the Python version of the algorithm and the discussion here https://stackoverflow.com/questions/12862226/the-implementation-of-calculating-the-number-of-days-between-2-dates.*//**Transform a date into a day number in the Gregorian Calendar*/defdateToDays(year:Int,month:Int,day:Int):Int={valm=(month+9)%12valy=year-m/10vald=day365*y+y/4-y/100+y/400+(m*306+5)/10+(d-1)}/**Compute the difference of days between both input dates*/defdaysDifference(firstDate:String,secondDate:String):Int={valfirstDateTuple=firstDate.split('-')match{caseArray(a,b,c)=>(a,b,c)}valsecondDateTuple=secondDate.split('-')match{caseArray(a,b,c)=>(a,b,c)}valfirstYear=dateToDays(firstDateTuple._1.toInt,firstDateTuple._2.toInt,firstDateTuple._3.toInt)valsecondYear=dateToDays(secondDateTuple._1.toInt,secondDateTuple._2.toInt,secondDateTuple._3.toInt)returnsecondYear-firstYear}defmain(args:Array[String]):Unit={println(daysDifference("2019-01-01","2019-09-30"))println(daysDifference("1995-11-21","1995-11-21"))println(daysDifference("2019-01-01","2019-01-02"))println(daysDifference("2019-01-02","2019-01-01"))println(daysDifference("2019-01-01","2019-03-01"))println(daysDifference("2020-01-01","2020-03-01"))println(daysDifference("1902-01-01","1968-12-25"))println(daysDifference("2090-01-01","2098-12-25"))println(daysDifference("1902-01-01","2098-12-25"))}}
27201-1596024465328071947
SenseTalk supports date and time calculations in many forms, and many different units of time (such as 'days' in this example). Rounding is needed due to daylight savings time changes.
set startDate to "2020-03-13"set endDate to "2021-07-14"put (endDate - startDate) rounded to nearest day
488 days
require('Date::Calc')funcdays_diff(a,b){%S<Date::Calc>.Delta_Days(a.split('-')...,b.split('-')...)}vardate1="1970-01-01"vardate2="2019-10-02"say"Date 1:#{date1}"say"Date 2:#{date2}"vardays=days_diff(date1,date2)say"There are#{days} days between these dates"
Date 1: 1970-01-01Date 2: 2019-10-02There are 18171 days between these dates
importFoundationfuncdaysFromTimeInterval(_interval:Double)->Int{returnInt(interval)/86400}letformatter=DateFormatter()formatter.dateFormat="yyyy-MM-dd"print("Enter date one (yyyy-MM-dd): ",terminator:"")guardletdate1Str=readLine(strippingNewline:true),letdate1=formatter.date(from:date1Str)else{fatalError("Invalid date two")}print("Enter date two (yyyy-MM-dd): ",terminator:"")guardletdate2Str=readLine(strippingNewline:true),letdate2=formatter.date(from:date2Str)else{fatalError("Invalid date two")}let(start,end)=date1>date2?(date2,date1):(date1,date2)letdays=daysFromTimeInterval(DateInterval(start:start,end:end).duration)print("There are\(days) days between\(start) and\(end)")
Enter date one (yyyy-MM-dd): 2019-01-01Enter date two (yyyy-MM-dd): 2019-12-02There are 335 days between 2019-01-01 05:00:00 +0000 and 2019-12-02 05:00:00 +0000
# return true if year is leap in Gregorian calendarleap(){local-iyearyear=$1if((year%4));thenreturn1;fiif((year%100));thenreturn0;fi!((year%400))}# convert date to Gregorian day count (Rata Die), where RD 1 = January 1, 1 CErd(){localyearmonthdayIFS=-readyearmonthday<<<"$1"local-ielapsed_years=year-1((day+=elapsed_years*365))((day+=elapsed_years/4))((day-=elapsed_years/100))((day+=elapsed_years/400))localmonth_lengths=(312831303130313130313031)ifleap"$year";thenletmonth_lengths[1]+=1;filocalmfor((m=0;m<month-1;++m));do((day+=month_lengths[m]))doneprintf'%d\n'"$day"}days_between(){local-idate1date2date1=$(rd"$1")date2=$(rd"$2")printf'%d\n'$((date2-date1))}days_between1970-01-012019-12-04
18234
ImportsSystem.GlobalizationModuleModule1FunctionDateDiff(d1AsString,d2AsString)AsIntegerDima=DateTime.ParseExact(d1,"yyyy-MM-dd",CultureInfo.InvariantCulture)Dimb=DateTime.ParseExact(d2,"yyyy-MM-dd",CultureInfo.InvariantCulture)Return(b-a).TotalDaysEndFunctionSubMain()Console.WriteLine(DateDiff("1970-01-01","2019-10-18"))EndSubEndModule
18187
import timefn days_between(d1 string, d2 string) !int { t1 := time.parse('$d1 01:01:01')! t2 := time.parse('$d2 01:01:01')! days := int((t2-t1).hours()/24) return days}fn main(){ mut date1,mut date2 := "2019-01-01", "2019-09-30" mut days := days_between(date1, date2)! println("There are $days days between $date1 and $date2") date1, date2 = "2015-12-31", "2016-09-30" days = days_between(date1, date2)! println("There are $days days between $date1 and $date2")}There are 272 days between 2019-01-01 and 2019-09-30There are 274 days between 2015-12-31 and 2016-09-30
import"./date"forDatevardatePairs=[["1995-11-21","1995-11-21"],["2019-01-01","2019-01-02"],["2019-01-02","2019-01-01"],["2019-01-01","2019-03-01"],["2020-01-01","2020-03-01"],["1902-01-01","1968-12-25"],["2090-01-01","2098-12-25"],["1902-01-01","2098-12-25"],["1970-01-01","2019-10-18"],["2019-03-29","2029-03-29"],["2020-02-29","2020-03-01"]]Date.default=Date.isoDatefor(datesindatePairs){vardate1=Date.parse(dates[0])vardate2=Date.parse(dates[1])vardays=(date2-date1).daysSystem.print("Days between%(date1) and%(date2) =%(days)")}
Days between 1995-11-21 and 1995-11-21 = 0Days between 2019-01-01 and 2019-01-02 = 1Days between 2019-01-02 and 2019-01-01 = -1Days between 2019-01-01 and 2019-03-01 = 59Days between 2020-01-01 and 2020-03-01 = 60Days between 1902-01-01 and 1968-12-25 = 24465Days between 2090-01-01 and 2098-12-25 = 3280Days between 1902-01-01 and 2098-12-25 = 71947Days between 1970-01-01 and 2019-10-18 = 18187Days between 2019-03-29 and 2029-03-29 = 3653Days between 2020-02-29 and 2020-03-01 = 1
func Gregorian(Y, M, D); \Return Gregorian day given dateint Y, M, D;int N, W;[N:= M + 9 - (M+9)/12*12;W:= Y - N/10;return 365*W + W/4 - W/100 + W/400 + (N*306+5)/10 + D - 1;];int Dates, N, Y, M, D, G0, G1;[Dates:= [ ["2019-01-01", "2019-01-02"], ["2019-01-02", "2019-01-01"], ["2019-01-01", "2019-03-01"], ["2020-01-01", "2020-03-01"], ["1995-11-21", "1995-11-21"], ["2090-01-01", "2098-12-25"] ];OpenO(8); OpenI(8);for N:= 0 to 6-1 do [Text(8, Dates(N,0)); Y:= IntIn(8); M:= IntIn(8); D:= IntIn(8); G0:= Gregorian(Y, M, D); Text(8, Dates(N,1)); Y:= IntIn(8); M:= IntIn(8); D:= IntIn(8); G1:= Gregorian(Y, M, D); Text(0, "Number of days between "); Text(0, Dates(N,0)); Text(0, " and "); Text(0, Dates(N,1)); Text(0, " is "); IntOut(0, abs(G1-G0)); CrLf(0); ];]
Number of days between 2019-01-01 and 2019-01-02 is 1Number of days between 2019-01-02 and 2019-01-01 is 1Number of days between 2019-01-01 and 2019-03-01 is 59Number of days between 2020-01-01 and 2020-03-01 is 60Number of days between 1995-11-21 and 1995-11-21 is 0Number of days between 2090-01-01 and 2098-12-25 is 3280
var [const] TD=Time.Date;today:=TD.parseDate("--"); // "yyyy-mm-dd" and variations --> (y,m,d)// or Time.Clock.UTC --> (y,m,d,h,m,s)then:=TD.parseDate("2018-9-30");diff:=TD.deltaDays(then,today.xplode()); // ( (y,m,d), y,m,d )println("Number of days between %s and %s: %d".fmt(then,today,diff));println("Number of days between %s and %s: %d".fmt( TD.toYMDString(today.xplode()),// to(y,m,d) not to((y,m,d)) TD.toYMDString(then.xplode()), TD.deltaDays(today,then.xplode())));Number of days between L(2018,9,30) and L(2019,9,30): 365Number of days between 2019-09-30 and 2018-09-30: -365