Days between dates: Difference between revisions
no edit summary
(Added solution for Action!) |
No edit summary |
||
(23 intermediate revisions by 14 users not shown) | |||
Line 12:
=={{header|11l}}==
<
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())</
{{out}}
Line 26:
=={{header|Action!}}==
{{libheader|Action! Tool Kit}}
<
TYPE Date=[CARD year BYTE month,day]
Line 109:
Test("2090-01-01","2098-12-25")
Test("1902-01-01","2098-12-25")
RETURN</
{{out}}
[https://gitlab.com/amarok8bit/action-rosetta-code/-/raw/master/images/Days_between_dates.png Screenshot from Atari 8-bit computer]
Line 124:
=={{header|Ada}}==
<
with Ada.Text_IO;
with Ada.Integer_Text_IO;
Line 168:
Put_Days_Between ("2090-01-01", "2098-12-25", "Future");
Put_Days_Between ("1902-01-01", "2098-12-25", "Long span");
end Days_Between_Dates;</
{{out}}
Line 179:
Days between 2090-01-01 and 2098-12-25 is 3280 days -- Future
Days between 1902-01-01 and 2098-12-25 is 71947 days -- Long span</pre>
=={{header|ALGOL 68}}==
{{Trans|FreeBASIC}}
<syntaxhighlight lang="algol68">
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 ) )
OD
END
</syntaxhighlight>
{{out}}
<pre>
Days between 1902-01-01 and 1968-12-25 is 24465 days
Days between 2019-01-01 and 2019-01-02 is 1 days
Days between 2019-01-02 and 2019-01-01 is -1 days
Days between 2019-01-01 and 2019-03-01 is 59 days
Days between 2020-01-01 and 2020-03-01 is 60 days
Days between 1995-11-21 and 1995-11-21 is 0 days
Days between 2090-01-01 and 2098-12-25 is 3280 days
</pre>
=={{header|ALGOL W}}==
{{Trans|FreeBASIC}}
<syntaxhighlight lang="algolw">
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.
</syntaxhighlight>
{{out}}
<pre>
Days between 1902-01-01 and 1968-12-25 is 24465 days
Days between 2019-01-01 and 2019-01-02 is 1 days
Days between 2019-01-02 and 2019-01-01 is -1 days
Days between 2019-01-01 and 2019-03-01 is 59 days
Days between 2020-01-01 and 2020-03-01 is 60 days
Days between 1995-11-21 and 1995-11-21 is 0 days
Days between 2090-01-01 and 2098-12-25 is 3280 days
</pre>
=={{header|AppleScript}}==
<
considering numeric strings -- Allows for leading zeros having been omitted.
if (date1 = date2) then return date1 & " and " & date2 & " are the same date"
Line 219 ⟶ 337:
return daysBetweenDates("2020-04-11", "2001-01-01") & linefeed & ¬
daysBetweenDates("2020-04-11", "2020-04-12") & linefeed & ¬
daysBetweenDates("2020-04-11", "2020-04-11")</
{{output}}
Line 229 ⟶ 347:
Or, composing a function from reusable generics, and drawing on NSISO8601DateFormatter:
<
use framework "Foundation"
use scripting additions
Line 360 ⟶ 478:
set my text item delimiters to dlm
str
end unlines</
{{Out}}
<pre>2020-04-11 -> 2001-01-01 -> -7040 days
Line 371 ⟶ 489:
{{trans|Ruby}}
<
a: to :date.format: "dd/MM/yyyy" startDate
b: to :date.format: "dd/MM/yyyy" endDate
Line 381 ⟶ 499:
"days between the two dates:"
daysBetweenDates "01/01/2019" "19/10/2019"
]</
{{out}}
Line 388 ⟶ 506:
=={{header|AutoHotkey}}==
<syntaxhighlight lang="autohotkey">db =
(
1995-11-21|1995-11-21
Line 412 ⟶ 530:
EnvSub, D2, % D1, days
return D2
}</
{{out}}
<pre>Days between 1995-11-21 and 1995-11-21 : 0 Day(s)
Line 424 ⟶ 542:
=={{header|AWK}}==
<syntaxhighlight lang="awk">
# syntax: GAWK -f DAYS_BETWEEN_DATES.AWK
BEGIN {
Line 466 ⟶ 584:
return(result)
}
</syntaxhighlight>
{{out}}
<pre>
Line 499 ⟶ 617:
=={{header|C}}==
<syntaxhighlight lang="c">
#include<stdbool.h>
#include<string.h>
Line 559 ⟶ 677:
return 0;
}
</syntaxhighlight>
Output :
<pre>
Line 565 ⟶ 683:
Days Difference : 335
</pre>
=={{header|BQN}}==
The <code>date</code> namespace is taken from bqn-libs. <code>DBw</code> is the final function which calculates the proper difference between two date strings.
<syntaxhighlight lang="bqn">DivMod ← ⌊∘÷˜ ⋈ |
date ← {
o ← 719469
y ← 365.25
dur ← ⟨(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 × (100 DivMod y-f) ∾ ⟨m+12×f⟩
}
To ⇐ {
t←𝕩
c‿y‿m ← dur { d‿m ← 𝕨 DivMod 𝕩+t ⋄ t↩⌊m ⋄ d }¨ off
m -↩ 12×10≤m
⟨(100×c)+y+m<0, 3+m, 1+t⟩
}
}
Split←(⊢-˜+`׬)∘=⊔⊢
ToI←10⊸×⊸+˜´∘⌽-⟜'0'
S2D←ToI¨ '-'⊸Split
DBw ← -○(date.From S2D)</syntaxhighlight>
<pre> "2019-09-30" DBw "2019-01-01"
272</pre>
=={{header|C++}}==
{{trans|c}}
<
#include <iostream>
Line 704 ⟶ 854:
return 0;
}</
{{out}}
<pre>Days difference : 335</pre>
Line 710 ⟶ 860:
===Alternative using Boost===
{{libheader|Boost}}
<
#include <iostream>
#include <boost/date_time/gregorian/gregorian.hpp>
Line 729 ⟶ 879:
}
return EXIT_SUCCESS;
}</
{{out}}
Line 737 ⟶ 887:
</pre>
=={{header|C sharp|C#}}==
<
using System.Globalization;
Line 750 ⟶ 900:
return (int)(b - a).TotalDays;
}
}</
{{out}}
<pre>
Line 759 ⟶ 909:
{{works with|GnuCOBOL}}
<
*> Tectonics: cobc -xj days-between.cob
Line 779 ⟶ 929:
goback.
end program days-between.</
{{out}}
Line 788 ⟶ 938:
=={{header|Commodore BASIC}}==
<syntaxhighlight lang="gwbasic">
100 REM ===============================
110 REM DAYS BETWEEN 2 DATES
Line 840 ⟶ 990:
9080 G=G+INT((N*306+5)/10)+(D-1)
9090 RETURN
</syntaxhighlight>
Line 847 ⟶ 997:
=={{header|D}}==
<
import std.stdio;
Line 855 ⟶ 1,005:
auto diff = toDate - fromDate;
writeln("Number of days between ", fromDate, " and ", toDate, ": ", diff.total!"days");
}</
{{out}}
<pre>Number of days between 2019-Jan-01 and 2019-Oct-07: 279</pre>
Line 861 ⟶ 1,011:
{{libheader| System.SysUtils}}
{{Trans|C#}}
<syntaxhighlight lang="delphi">
program Days_between_dates;
Line 893 ⟶ 1,043:
Writeln(DaysBetween('1970-01-01', '2019-10-18'));
readln;
end.</
{{out}}
<pre>18187</pre>
=={{header|Erlang}}==
<
-module(daysbetween).
Line 920 ⟶ 1,070:
</
{{out}}
erlang shell:
Line 1,034 ⟶ 1,184:
=={{header|F_Sharp|F#}}==
<
// Days between dates: Nigel Galloway. June 3rd., 2021
let n,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).Days n.Year n.Month n.Day g.Year g.Month g.Day
</syntaxhighlight>
{{out}}
<pre>
Line 1,045 ⟶ 1,195:
=={{header|Factor}}==
Factor supports the addition and subtraction of timestamps and durations with the <code>time+</code> and <code>time-</code> words.
<
: days-between ( ymd-str ymd-str -- n )
Line 1,051 ⟶ 1,201:
"2019-01-01" "2019-09-30" days-between .
"2016-01-01" "2016-09-30" days-between . ! leap year</
{{out}}
<pre>
Line 1,060 ⟶ 1,210:
=={{header|FreeBASIC}}==
<
Dim As Integer Y1, M1, D1, Y2, M2, D2, G1, G2
Dim As String DaysBetween(7, 2) = {{"1902-01-01","1968-12-25"}, _
Line 1,087 ⟶ 1,237:
Print Using "##### days"; (G2-G1)
Next n
Sleep</
{{out}}
<pre>
Line 1,098 ⟶ 1,248:
Days between 2090-01-01 and 2098-12-25 is 3280 days
</pre>
=={{header|Frink}}==
Line 1,107 ⟶ 1,256:
See Frink's [https://frinklang.org/#DateTimeHandling Date/Time Handling] documentation to see how easy it is to work with dates, times, timezones, calendrical systems, and even leap seconds correctly and easily.
<
d2 = # 2020-12-06 #
println[d1-d2 -> days]</
{{out}}
Line 1,117 ⟶ 1,266:
=={{header|Fōrmulæ}}==
{{FormulaeEntry|page=https://formulae.org/?timeZone=America%2FLos_Angeles&script=examples/Days_between_dates}}
'''Solution'''
Note. For this script, the time zone is intentionally set to America/Los_Angeles, because it observes [https://en.wikipedia.org/wiki/Daylight_saving_time daylight 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 the [https://en.wikipedia.org/wiki/Epoch_(computing) epoch]:
[[File:Fōrmulæ - Days between dates 01.png]]
[[File:Fōrmulæ - Days between dates 02.png]]
The solution seems easy, calculating the difference between two times (in milliseconds), and dividing by 86,4000,000 (number of milliseconds in a day):
[[File:Fōrmulæ - Days between dates 03.png]]
[[File:Fōrmulæ - Days between dates 04.png]]
However, it does not work if one time is in daylight saving time, and the other one is in standard time:
[[File:Fōrmulæ - Days between dates 05.png]]
[[File:Fōrmulæ - Days between dates 06.png]]
[[File:Fōrmulæ - Days between dates 07.png]]
[[File:Fōrmulæ - Days between dates 08.png]]
'''Solution 1'''
The first solution consists in simply rounding the result to the nearest integer:
[[File:Fōrmulæ - Days between dates 09.png]]
[[File:Fōrmulæ - Days between dates 10.png]]
'''Solution 2'''
The expression GetTimeZoneOffset reduces to the offset (in minutes) of the given time.
[[File:Fōrmulæ - Days between dates 11.png]]
[[File:Fōrmulæ - Days between dates 12.png]]
[[File:Fōrmulæ - Days between dates 13.png]]
[[File:Fōrmulæ - Days between dates 14.png]]
The solution consist in taking this difference in account.
So, the function that works correctly is:
[[File:Fōrmulæ - Days between dates 15.png]]
'''Test cases'''
[[File:Fōrmulæ - Days between dates 16.png]]
[[File:Fōrmulæ - Days between dates 17.png]]
Notice that it works even for fractions of days:
[[File:Fōrmulæ - Days between dates 18.png]]
[[File:Fōrmulæ - Days between dates 19.png]]
=={{header|Go}}==
<
import (
Line 1,161 ⟶ 1,370:
days = daysBetween(date1, date2)
fmt.Printf("There are %d days between %s and %s\n", days, date1, date2)
}</
{{out}}
Line 1,171 ⟶ 1,380:
=={{header|Groovy}}==
{{trans|Kotlin}} {{trans|Java}}
<
def fromDate = LocalDate.parse("2019-01-01")
def toDate = LocalDate.parse("2019-10-19")
def diff = fromDate - toDate
println "Number of days between ${fromDate} and ${toDate}: ${diff}"</
{{out}}
<pre>Number of days between 2019-01-01 and 2019-10-19: 291</pre>
=={{header|Haskell}}==
<
import Data.Time.Calendar (diffDays)
import Data.Time.Format (parseTimeM,defaultTimeLocale)
Line 1,200 ⟶ 1,409:
stringToDay :: String -> Maybe Day
stringToDay date = parseTimeM True defaultTimeLocale "%Y-%-m-%-d" date</
{{out}}
<pre>There are 272 days between 2019-01-01 and 2019-09-30.
Line 1,207 ⟶ 1,416:
Or, composing rather than raising errors:
<
import Data.Time.Calendar (diffDays)
import Data.Time.Format (defaultTimeLocale, parseTimeM)
Line 1,216 ⟶ 1,425:
daysBetween s1 s2 =
dayFromString s2
>>=
dayFromString :: String -> Maybe Day
Line 1,252 ⟶ 1,458:
]
)
$ daysBetween s1 s2</
{{Out}}
<pre>There are 272 days between 2019-01-01 and 2019-09-30.
Line 1,275 ⟶ 1,481:
=={{header|Java}}==
{{trans|Kotlin}}
<
import java.time.temporal.ChronoUnit;
Line 1,285 ⟶ 1,491:
System.out.printf("Number of days between %s and %s: %d\n", fromDate, toDate, diff);
}
}</
{{out}}
<pre>Number of days between 2019-01-01 and 2019-10-19: 291</pre>
=={{header|JavaScript}}==
<
var floor = Math.floor, abs = Math.abs;
var daysBetween = (d1, d2) => floor(abs(new Date(d1) - new Date(d2)) / timeRatio);
console.log('Days between 2021-10-27 and 2020-03-03: %s', daysBetween('2021-10-27', '2020-03-03'));</
{{out}}
<pre>Days between 2021-10-27 and 2020-03-03: 603</pre>
Line 1,308 ⟶ 1,514:
===Using jq's built-ins===
<syntaxhighlight lang="jq">
def days_between(yyyymmddBefore; yyyymmddAfter):
(yyyymmddBefore | strptime("%Y-%m-%d") | mktime) as $before
Line 1,338 ⟶ 1,544:
task
</syntaxhighlight>
{{out}}
<pre>
Line 1,360 ⟶ 1,566:
===From first principles===
'''Adapted from [[#Wren|Wren]]'''
<syntaxhighlight lang="jq">
# 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
Line 1,403 ⟶ 1,609:
| (date | toa) as $date
| days_between($date[0]; $date[1]; $date[2]; $later[0]; $later[1]; $later[2]);
</syntaxhighlight>
'''The Tasks'''
Line 1,412 ⟶ 1,618:
=={{header|Julia}}==
<
@show Day(DateTime("2019-09-30") - DateTime("2019-01-01"))
Line 1,421 ⟶ 1,627:
@show Day(DateTime("2029-03-29") - DateTime("2019-03-29"))
</
<pre>
Day(DateTime("2019-09-30") - DateTime("2019-01-01")) = 272 days
Line 1,430 ⟶ 1,636:
=={{header|Kotlin}}==
<
import java.time.temporal.ChronoUnit
Line 1,438 ⟶ 1,644:
val diff = ChronoUnit.DAYS.between(fromDate, toDate)
println("Number of days between $fromDate and $toDate: $diff")
}</
{{out}}
<pre>Number of days between 2019-01-01 and 2019-10-19: 291</pre>
Line 1,444 ⟶ 1,650:
=={{header|Lua}}==
This uses os.difftime to compare two Epoch times. Not to be used with dates before 1970.
<
-- Convert date string as YYYY-MM-DD to Epoch time.
Line 1,458 ⟶ 1,664:
local d2 = parseDate(io.read())
local diff = math.ceil(os.difftime(d2, d1) / SECONDS_IN_A_DAY)
print("There are " .. diff .. " days between these dates.")</
{{out}}
<pre>Enter date 1: 1970-01-01
Enter date 2: 2019-10-02
There are 18171 days between these dates.</pre>
=={{header|M2000 Interpreter}}==
Version 12 has date type, so we can handle easy dates.
<syntaxhighlight lang="m2000 interpreter">
module Days_between_dates{
date a="2019-01-01", b="2019-09-30"
long z=b-a
// Use the system default to display dates (DD/MM/YYYY)
Print "Days from "+a+" to "+b+" = "+z
// using locale 1033 to display dates (MM/DD/YYYY)
Print "Days from "+date$(a, 1033)+" to "+date$(b, 1033)+" = "+z
}
Days_between_dates
</syntaxhighlight>
{{out}}
<pre>
Days from 1/1/2019 to 30/9/2019 = 272
Days from 1/1/2019 to 9/30/2019 = 272
</pre>
=={{header|Mathematica}} / {{header|Wolfram Language}}==
<
DateDifference["2021-01-01", "2021-03-01"]</
{{out}}
<pre>Quantity[60, "Days"]
Line 1,472 ⟶ 1,699:
=={{header|Nim}}==
<
proc daysBetween(date1, date2: string): int64 =
Line 1,487 ⟶ 1,714:
for (date1, date2) in Dates:
echo "Days between ", date1, " and ", date2, ": ", daysBetween(date1, date2)</
{{out}}
Line 1,497 ⟶ 1,724:
Days between 1902-01-01 and 1968-12-25: 24465
Days between 2090-01-01 and 2098-12-25: 3280</pre>
=={{header|Pascal}}==
==={{header|Free Pascal}}===
<syntaxhighlight lang="pascal">
Program DaysBetweenDates;
{$mode ObjFPC}{$H+}
Uses dateutils,strutils;
Type Tarr = array of array Of string;
Const lst : 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'));
Function strtodate(str : String) : tdatetime;
Begin
result := ScanDateTime('YYYYMMDD', DelChars(str, '-'));
End;
Var arr : array of string;
DaysBetw : integer;
Begin
For arr In lst Do
Begin
DaysBetw := DaysBetween(strtodate(arr[0]),strtodate(arr[1]));
writeln(arr[0],' - ',arr[1],' -> ',DaysBetw);
End;
End.
</syntaxhighlight>
{{out}}
<pre>
1902-01-01 - 1968-12-25 -> 24465
2019-01-01 - 2019-01-02 -> 1
2019-01-02 - 2019-01-01 -> 1
2019-01-01 - 2019-03-01 -> 59
2020-01-01 - 2020-03-01 -> 60
1995-11-21 - 1995-11-21 -> 0
2090-01-01 - 2098-12-25 -> 3280
1967-02-23 - 2024-03-21 -> 20846
</pre>
=={{header|Perl}}==
Would not reinvent this wheel.
<
use Date::Calc qw(Delta_Days);
Line 1,507 ⟶ 1,776:
say Delta_Days(2000,1,1, 2100,1,1); # another, with one extra leap day
say Delta_Days(2020,1,1, 2019,10,1); # backwards in time
say Delta_Days(2019,2,29, 2019,3,1); # croaks</
{{out}}
<pre>427
Line 1,517 ⟶ 1,786:
=={{header|Phix}}==
{{libheader|Phix/basics}}
<!--<
<span style="color: #008080;">include</span> <span style="color: #000000;">builtins<span style="color: #0000FF;">\<span style="color: #004080;">timedate<span style="color: #0000FF;">.<span style="color: #000000;">e</span>
<span style="color: #000080;font-style:italic;">-- specify as many or as few permitted formats as you like:</span>
Line 1,539 ⟶ 1,808:
<span style="color: #000000;">test<span style="color: #0000FF;">(<span style="color: #008000;">"1970-01-01"<span style="color: #0000FF;">,</span> <span style="color: #008000;">"2019/10/18"<span style="color: #0000FF;">)</span>
<span style="color: #000000;">test<span style="color: #0000FF;">(<span style="color: #008000;">"1970-01-01"<span style="color: #0000FF;">,</span> <span style="color: #008000;">"18/10/2019"<span style="color: #0000FF;">)
<!--</
As shown, timedate_diff() can optionally round to the nearest whole number of days [else omit DT_DAY].<br>
Note that elapsed() assumes all years are exactly 365 days, and in no way takes leap years into consideration
Line 1,556 ⟶ 1,825:
=={{header|PicoLisp}}==
<
(abs (- ($dat A "-") ($dat B "-"))) )
(println (diffDates "2019-1-1" "2019-9-30"))
(println (diffDates "2015-12-31" "2016-09-30"))</
{{out}}
<pre>
Line 1,566 ⟶ 1,835:
</pre>
=={{header|PL/I-80}}==
{{Trans|S-BASIC}}
<syntaxhighlight lang = "PL/I">
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;
</syntaxhighlight>
{{out}}
Test case taken from the Delphi example
<pre>
Elapsed Date Calculator
First date as YYYY-MM-DD : 1970-01-01
Second date as YYYY-MM-DD : 2019-10-18
Elapsed days = 18187
Do another (y/n)? n
</pre>
=={{header|PL/M}}==
{{Trans|FreeBASIC}}
{{works with|8080 PL/M Compiler}} ... under CP/M (or an emulator)<br>
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.
<syntaxhighlight lang="plm">
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
</syntaxhighlight>
{{out}}
<pre>
DAYS BETWEEN 1902-01-01 AND 1968-12-25 IS 24465
DAYS BETWEEN 2019-01-01 AND 2019-01-02 IS 1
DAYS BETWEEN 2019-01-02 AND 2019-01-01 IS -1
DAYS BETWEEN 2019-01-01 AND 2019-03-01 IS 59
DAYS BETWEEN 2020-01-01 AND 2020-03-01 IS 60
DAYS BETWEEN 1995-11-21 AND 1995-11-21 IS 0
DAYS BETWEEN 2090-01-01 AND 2098-12-25 IS 3280
</pre>
=={{header|Python}}==
<
#!/usr/bin/python
Line 1,600 ⟶ 2,017:
two = sys.argv[2]
print diff(one,two)
</
{{out}}
Line 1,606 ⟶ 2,023:
272
</pre>
=={{header|QB64}}==
<syntaxhighlight lang="qb64">
'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$)
End
Function 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 = NumberD
End Function
</syntaxhighlight>
=={{header|Raku}}==
(formerly Perl 6)
Dates are first class objects in Raku and may have arithmetic in days done directly on them.
<syntaxhighlight lang="raku"
say Date.new('2019-03-01') - Date.new('2019-02-01');
Line 1,624 ⟶ 2,107:
say Date.new('2019-02-29') + 30;
CATCH { default { .message.say; exit; } };</
<pre>272
Line 1,649 ⟶ 2,132:
<br>days since the beginning of the Gregorian calendar, and '''I''' which is the option that indicates the date is in
<br>the '''ISO''' (International Standards Organization standard 8601:2004) format.
<
parse arg $1 $2 . /*get 2 arguments (dates) from the C.L.*/
say abs( date('B',$1,"I") - date('B',$2,"I") ) ' days between ' $1 " and " $2
/*stick a fork in it, we're all done. */</
{{out|output|text= when using the inputs of: <tt> 2019-10-02 2000-01-01 </tt>}}
<pre>
Line 1,673 ⟶ 2,156:
Also, more informative error messages are generated.
<
parse arg $.1 $.2 _ . 1 . . xtra /*obtain two arguments from the C.L. */
seps= '/-\'; yr.= .; mon.= .; dd.= . /*define the defaults for both dates. */
Line 1,729 ⟶ 2,212:
if length(yr.a)==2 then yr.a= left( date('S'), 2)yr.a /*2 dig yy ?*/
if yr.a==. | mon.a==. | dd.a==. then call serDAT /*validate. */
return</
{{out|output|text= when using the inputs of: <tt> * 2000-1-1 </tt>}}
Line 1,738 ⟶ 2,221:
=={{header|Ring}}==
<
load "stdlib.ring"
Line 1,756 ⟶ 2,239:
? "Days between " + DaysBetween[n][1] + " and " + DaysBetween[n][2] + ": " + diffdays(date4,date3)
next
</syntaxhighlight>
{{out}}
<pre>
Line 1,766 ⟶ 2,249:
Days between 1902-01-01 and 1968-12-25: 0
Days between 2090-01-01 and 2098-12-25: 3280
</pre>
=={{header|RPL}}==
Uses Python formula, in a forced binary calculation mode to avoid 'flooring' instructions
{{works with|Halcyon Calc|4.2.7}}
≪ → 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 2 '''START'''
→ 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
{{out}}
<pre>
4: 24465
3: -1
2: 59
1: 60
</pre>
=={{header|Ruby}}==
<
d1, d2 = Date.parse("2019-1-1"), Date.parse("2019-10-19")
Line 1,775 ⟶ 2,290:
p (d1 - d2).to_i # => -291
p (d2 - d1).to_i # => 291
</syntaxhighlight>
=={{header|Rust}}==
<
// chrono = "0.4"
Line 1,801 ⟶ 2,316:
std::process::exit(1);
}
}</
{{out}}
Line 1,807 ⟶ 2,322:
days_between_dates 2020-01-01 2020-09-06
249
</pre>
=={{header|S-BASIC}}==
Error checking of entered dates is omitted in order to focus
on the stated task but would obviously have to be included
in production code.
<syntaxhighlight lang = "BASIC">
comment
Given a month, day, and year in the Gregorian calendar,
return a numeric date which is equal to the number of
days since the start of the Common era.
end
function serial_date(da, mo, yr = integer) = real
var n = real
n = 365 * yr + da + 31 * (mo - 1)
if mo >= 3 then
n = n - int(.4 * mo + 2.3)
else
yr = yr - 1
n = n + int(yr/4) - int(.75 * (int(yr/100) + 1))
end = n
comment
Read a date in YYYY-MM-DD format from the console and
return its serial date equivalent.
end
function get_date = real
var date = string : 20
var y, m, d = integer
input2 date
y = val(mid(date,1,4))
m = val(mid(date,6,2))
d = val(mid(date,9,2))
end = serial_date(d, m, y)
rem -- main program begins here
var date1, date2 = real
var another = char
repeat
begin
print "First date : ";
date1 = get_date
print "Second date : ";
date2 = get_date
print "Elapsed days = "; date2 - date1
input "Do another (y/n)"; another
end
until not another
end
</syntaxhighlight>
{{out}}
Test dates taken from Delphi example
<pre>
First date : 1970-01-01
Second date : 2019-10-18
Elapsed days = 18187
Do another (y/n)? n
</pre>
=={{header|Scala}}==
<
/*Inspired by the Python version of the algorithm and the discussion here
Line 1,847 ⟶ 2,422:
}
</syntaxhighlight>
{{out}}
<pre>
Line 1,863 ⟶ 2,438:
=={{header|SenseTalk}}==
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 endDate to "2021-07-14"
put (endDate - startDate) rounded to nearest day
</syntaxhighlight>
{{out}}
<pre>
Line 1,874 ⟶ 2,449:
=={{header|Sidef}}==
<
func days_diff(a,b) {
Line 1,888 ⟶ 2,463:
var days = days_diff(date1, date2)
say "There are #{days} days between these dates"</
{{out}}
<pre>
Line 1,898 ⟶ 2,473:
=={{header|Swift}}==
<
func daysFromTimeInterval(_ interval: Double) -> Int {
Line 1,923 ⟶ 2,498:
let days = daysFromTimeInterval(DateInterval(start: start, end: end).duration)
print("There are \(days) days between \(start) and \(end)")</
{{out}}
Line 1,934 ⟶ 2,509:
{{works with|Bourne Again Shell}}
<
leap() {
local -i year
Line 1,969 ⟶ 2,544:
days_between 1970-01-01 2019-12-04
</syntaxhighlight>
{{Out}}
Line 1,976 ⟶ 2,551:
=={{header|Visual Basic .NET}}==
{{trans|C#}}
<
Module Module1
Line 1,990 ⟶ 2,565:
End Sub
End Module</
{{out}}
<pre>18187</pre>
=={{header|V (Vlang)}}==
{{trans|go}}
<syntaxhighlight lang="v (vlang)">import time
fn 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")
}</syntaxhighlight>
{{out}}
<pre>
There are 272 days between 2019-01-01 and 2019-09-30
There are 274 days between 2015-12-31 and 2016-09-30</pre>
=={{header|Wren}}==
{{libheader|Wren-date}}
<
var datePairs = [
Line 2,011 ⟶ 2,610:
["2020-02-29", "2020-03-01"]
]
Date.default = Date.isoDate
for (dates in datePairs) {
var date1 = Date.parse(dates[0])
var date2 = Date.parse(dates[1])
var days = (date2 - date1).days
System.print("Days between %(date1) and %(date2) = %(days)")
}</
{{out}}
Line 2,032 ⟶ 2,631:
Days between 2019-03-29 and 2029-03-29 = 3653
Days between 2020-02-29 and 2020-03-01 = 1
</pre>
=={{header|XPL0}}==
{{trans|FreeBASIC}}
<syntaxhighlight lang "XPL0">func Gregorian(Y, M, D); \Return Gregorian day given date
int 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);
];
]</syntaxhighlight>
{{out}}
<pre>
Number of days between 2019-01-01 and 2019-01-02 is 1
Number of days between 2019-01-02 and 2019-01-01 is 1
Number of days between 2019-01-01 and 2019-03-01 is 59
Number of days between 2020-01-01 and 2020-03-01 is 60
Number of days between 1995-11-21 and 1995-11-21 is 0
Number of days between 2090-01-01 and 2098-12-25 is 3280
</pre>
=={{header|zkl}}==
<
today:=TD.parseDate("--"); // "yyyy-mm-dd" and variations --> (y,m,d)
// or Time.Clock.UTC --> (y,m,d,h,m,s)
Line 2,044 ⟶ 2,683:
TD.toYMDString(today.xplode()), // to(y,m,d) not to((y,m,d))
TD.toYMDString(then.xplode()),
TD.deltaDays(today,then.xplode())));</
{{out}}
<pre>
|