9
\$\begingroup\$

How long ago was this?

The Rules

  • Each submission must be a full program.
  • The program must take input as two comma-separated dates in the form YYYY-MM-DD, and print the number of days that has passed since the second date to STDOUT as if today was the first date (if the second date would be in the future, output a negative number) plus an optional trailing newline, and nothing else. Assume both dates are in the Gregorian calendar.
  • The program must not write anything to STDERR.

    Note that there must be an interpreter so the submission can be tested.

  • Submissions are scored in bytes, in an appropriate (pre-existing) encoding, usually (but not necessarily) UTF-8. Some languages, like Folders, are a bit tricky to score - if in doubt, please ask on Meta.
  • This is , so shortest code wins

    Examples

Input:

2015-12-03,2015-12-01

Output:

2

Input:

2015-12-03,2014-12-01

Output:

367

Input:

2015-12-03,2013-12-03

Output:

730

The Snippet

The Stack Snippet at the bottom of this post generates the catalogue from the answers a) as a leaderboard and b) as a list of winners per language.

To make sure that your answer shows up, please start your answer with a headline, using the following Markdown template:

## Language Name, N bytes

where N is the size of your submission. If you improve your score, you can keep old scores in the headline, by striking them through. For instance:

## Ruby, <s>104</s> <s>101</s> 96 bytes

If there you want to include multiple numbers in your header (e.g. because your score is the sum of two files or you want to list interpreter flag penalties separately), make sure that the actual score is the last number in the header:

## Perl, 43 + 2 (-p flag) = 45 bytes

You can also make the language name a link which will then show up in the snippet:

## [><>](http://esolangs.org/wiki/Fish), 121 bytes

var QUESTION_ID=65989,OVERRIDE_USER=46167;function answersUrl(e){return"http://api.stackexchange.com/2.2/questions/"+QUESTION_ID+"/answers?page="+e+"&pagesize=100&order=desc&sort=creation&site=codegolf&filter="+ANSWER_FILTER}function commentUrl(e,s){return"http://api.stackexchange.com/2.2/answers/"+s.join(";")+"/comments?page="+e+"&pagesize=100&order=desc&sort=creation&site=codegolf&filter="+COMMENT_FILTER}function getAnswers(){jQuery.ajax({url:answersUrl(answer_page++),method:"get",dataType:"jsonp",crossDomain:!0,success:function(e){answers.push.apply(answers,e.items),answers_hash=[],answer_ids=[],e.items.forEach(function(e){e.comments=[];var s=+e.share_link.match(/\d+/);answer_ids.push(s),answers_hash[s]=e}),e.has_more||(more_answers=!1),comment_page=1,getComments()}})}function getComments(){jQuery.ajax({url:commentUrl(comment_page++,answer_ids),method:"get",dataType:"jsonp",crossDomain:!0,success:function(e){e.items.forEach(function(e){e.owner.user_id===OVERRIDE_USER&&answers_hash[e.post_id].comments.push(e)}),e.has_more?getComments():more_answers?getAnswers():process()}})}function getAuthorName(e){return e.owner.display_name}function process(){var e=[];answers.forEach(function(s){var r=s.body;s.comments.forEach(function(e){OVERRIDE_REG.test(e.body)&&(r="<h1>"+e.body.replace(OVERRIDE_REG,"")+"</h1>")});var a=r.match(SCORE_REG);a&&e.push({user:getAuthorName(s),size:+a[2],language:a[1],link:s.share_link})}),e.sort(function(e,s){var r=e.size,a=s.size;return r-a});var s={},r=1,a=null,n=1;e.forEach(function(e){e.size!=a&&(n=r),a=e.size,++r;var t=jQuery("#answer-template").html();t=t.replace("{{PLACE}}",n+".").replace("{{NAME}}",e.user).replace("{{LANGUAGE}}",e.language).replace("{{SIZE}}",e.size).replace("{{LINK}}",e.link),t=jQuery(t),jQuery("#answers").append(t);var o=e.language;/<a/.test(o)&&(o=jQuery(o).text()),s[o]=s[o]||{lang:e.language,user:e.user,size:e.size,link:e.link}});var t=[];for(var o in s)s.hasOwnProperty(o)&&t.push(s[o]);t.sort(function(e,s){return e.lang>s.lang?1:e.lang<s.lang?-1:0});for(var c=0;c<t.length;++c){var i=jQuery("#language-template").html(),o=t[c];i=i.replace("{{LANGUAGE}}",o.lang).replace("{{NAME}}",o.user).replace("{{SIZE}}",o.size).replace("{{LINK}}",o.link),i=jQuery(i),jQuery("#languages").append(i)}}var ANSWER_FILTER="!t)IWYnsLAZle2tQ3KqrVveCRJfxcRLe",COMMENT_FILTER="!)Q2B_A2kjfAiU78X(md6BoYk",answers=[],answers_hash,answer_ids,answer_page=1,more_answers=!0,comment_page;getAnswers();var SCORE_REG=/<h\d>\s*([^\n,]*[^\s,]),.*?([\d.]+)(?=[^\n\d<>]*(?:<(?:s>[^\n<>]*<\/s>|[^\n<>]+>)[^\n\d<>]*)*<\/h\d>)/,OVERRIDE_REG=/^Override\s*header:\s*/i;
body{text-align:left!important}#answer-list,#language-list{padding:10px;width:290px;float:left}table thead{font-weight:700}table td{padding:5px}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script> <link rel="stylesheet" type="text/css" href="//cdn.sstatic.net/codegolf/all.css?v=83c949450c8b"> <div id="answer-list"> <h2>Leaderboard</h2> <table class="answer-list"> <thead> <tr><td></td><td>Author</td><td>Language</td><td>Size</td></tr></thead> <tbody id="answers"> </tbody> </table> </div><div id="language-list"> <h2>Winners by Language</h2> <table class="language-list"> <thead> <tr><td>Language</td><td>User</td><td>Score</td></tr></thead> <tbody id="languages"> </tbody> </table> </div><table style="display: none"> <tbody id="answer-template"> <tr><td>{{PLACE}}</td><td>{{NAME}}</td><td>{{LANGUAGE}}</td><td>{{SIZE}}</td><td><a href="{{LINK}}">Link</a></td></tr></tbody> </table> <table style="display: none"> <tbody id="language-template"> <tr><td>{{LANGUAGE}}</td><td>{{NAME}}</td><td>{{SIZE}}</td><td><a href="{{LINK}}">Link</a></td></tr></tbody> </table>

\$\endgroup\$
  • 1
    \$\begingroup\$ Related \$\endgroup\$ – GamrCorps Dec 8 '15 at 1:57
  • 1
    \$\begingroup\$ Are we allowed to use external libraries? Ones that are common in a given ecosystem but are not part of the standard lib? (For example, no one uses the JDK's Date APIs but JodaTime instead, even though it is technically an external library). \$\endgroup\$ – Ruslan Dec 8 '15 at 4:32
  • \$\begingroup\$ I assume everything uses UTC, since in my timezone the difference between 2015-11-01T00:00:00 and 2015-11-02T00:00:00 was only ~0.96 days (23 hours) due to daylight savings. You didn't mention anything about rounding fractional days, so you might want to clarify this in the question. (I think a lot of datetime libraries default to using local time.) \$\endgroup\$ – ThisSuitIsBlackNot Dec 8 '15 at 15:51
  • 1
    \$\begingroup\$ What is the case for leap years? \$\endgroup\$ – TheCoffeeCup Dec 8 '15 at 23:05
  • \$\begingroup\$ @TheCoffeeCup they must be handled \$\endgroup\$ – ev3commander Dec 9 '15 at 1:20

24 Answers 24

1
\$\begingroup\$

TeaScript, 24 bytes

((a=D.parse)×-a(y©/864e5

Uses Date.parse to parse the date, then get's the difference and divides.

Try it online

Explanation && Ungolfed

((a=D.parse)(x)-a(y))/864e5

               // Implicit: x is first date
               // y is second date
(
 (a=D.parse)   // Assign Date.parse to 'a'
 (x)           // Run Date.parse with first date
 -a(y)         // Subtract Date.parse run with second date
)/864e5        // Divide by 86,400,000
\$\endgroup\$
13
\$\begingroup\$

Bash + GNU utilities, 37

tr , \\n|date -f- +%s|dc -e??-86400/p

tr replaces the comma with a newline. date reads the newline separated dates and outputs the number of seconds since the Unix epoch that the passed-in date represents. These numbers are then put on the dc stack. Then its a simple matter of subtraction and divide by (24*60*60). In this case, dc stack-based RPN arithmetic evaluation is better than bc or bash $( ), mostly because the subraction-before-division needs no parentheses.

Input via STDIN:

$ echo 2015-12-3,2015-12-1 | ./longago.sh
2
$ echo 2015-12-3,2014-12-1 | ./longago.sh
367
$ echo 2015-12-3,2013-12-3 | ./longago.sh
730
$ 
\$\endgroup\$
4
\$\begingroup\$

Julia, 67 bytes

print(Int(-diff(map(i->Date(i,"y-m-d"),split(readline(),",")))[1]))

Ungolfed:

# Read a line from STDIN
r = readline()

# Split it into two character dates
s = split(r, ",")

# Convert each to a Date object
d = map(i -> Date(i, "y-m-d"), s)

# Compute the difference in dates (first-second)
f = diff(d)[1]

# Convert the Base.Date.Day object to an integer
# Negate to get second-first
i = Int(-f)

# Print to STDOUT
print(i)
\$\endgroup\$
  • \$\begingroup\$ Instead of -diff(d)[1] you can use -(d...) to save a couple of bytes. What Julia version are you using by the way? On 1.2, I had to explicitly import Dates and I also can't just convert days to integers like this. \$\endgroup\$ – user3263164 Aug 21 at 10:49
4
\$\begingroup\$

Scala, 166 139 120 116 92 bytes

print(args(0).replace('-','/').split(",").map(java.util.Date.parse(_)/86400000).reduce(_-_))

Usage: scala [source filename].scala [date1],[date2]

Note: The third version (120 bytes) and on uses a deprecated API. It still compiles and works fine. Note2: Thanks to the commenters below for the great advice!

\$\endgroup\$
  • \$\begingroup\$ Since the trailing new line is optional you could use print instead of println. \$\endgroup\$ – Marth Dec 8 '15 at 11:55
  • \$\begingroup\$ You can remove the Object A extends App{...} part and save it as a.scala and run it with scala a.scala 2015-12-3,2015-12-1 ;) \$\endgroup\$ – Martijn Dec 8 '15 at 15:12
  • \$\begingroup\$ @MartijnR Genius! Thanks!! \$\endgroup\$ – Ruslan Dec 8 '15 at 23:51
3
\$\begingroup\$

Ruby, 69 66 65 57 55 bytes

a=->l{Time.gm *$F[l,3]};p (a[0]-a[3]).div 86400

47 bytes + 8 bytes for command line option. Thanks to Dane Anderson, saved 2 bytes.

57 bytes

p (Time.gm(*$F[0,3])-Time.gm(*$F[3,3])).div 86400

49 bytes code + 8 bytes for command line option. Saved 8 bytes with manatwork's suggestion.

65 bytes

a,b=gets.split(?,).map{|i|Time.gm *i.split(?-)};p (a-b).div 86400

66 bytes

a,b=gets.split(?,).map{|i|Time.new *i.split(?-)};p (a-b).div 86400

69 bytes

a,b=gets.split(',').map{|i|Time.new *i.split('-')};p (a-b).to_i/86400

Test it online

Ungolfed

a = -> l {
  Time.gm *$F[l,3]       # Anonymous method to parse time
}
p (a[0]-a[3]).div 86400  # Subtracts two times and divides by 24*60*60

Usage:

ruby -naF[,-] -e 'a=->l{Time.gm *$F[l,3]};p (a[0]-a[3]).div 86400' <<< '2015-12-3,2013-12-3'

=> 730
\$\endgroup\$
  • \$\begingroup\$ Three little chars: ','?,, '-'?-, to_i/div . \$\endgroup\$ – manatwork Dec 8 '15 at 9:59
  • \$\begingroup\$ Using some command line options may reduce it more: ruby -naF[,-] -e 'p (Time.new(*$F[0,3])-Time.new(*$F[3,3])).div 86400' <<< '2015-10-11,2015-07-11' is 59 characters as I count it. \$\endgroup\$ – manatwork Dec 8 '15 at 10:17
  • \$\begingroup\$ @manatwork Not sure if that is allowed. \$\endgroup\$ – Vasu Adari Dec 8 '15 at 11:11
  • \$\begingroup\$ The rule is that the minimum necessity needed to pass the code (in case of Ruby -e) is free, everything else has to be included in the count. There are different opinions on what exactly is that everything else. For example some members include the option separator space character and quotes around parameter values. In my view should only be counted what actually gets passed to the interpreter, extra characters required by shell syntax not. But can't remember any voice raised to disallow the use of options. \$\endgroup\$ – manatwork Dec 8 '15 at 11:24
  • 2
    \$\begingroup\$ almost not worth mentioning, but you can shave a byte by moving the repeated code into a proc: t=->l{Time.gm(*$F[l,3])};p (t[0]-t[3]).div 86400 \$\endgroup\$ – Alexis Andersen Dec 8 '15 at 17:52
2
\$\begingroup\$

Japt, 41 bytes

A=K$.parse)(($B=Uq',  g0)-$A($Bg1))/864e5

So far this is the best I can get it as all the variables and $ and parenthesis really kill the byte count.

Try it online

Explanation

             // Implicit: U is set to input
A=K$.parse)  // Set variable A to date parsing function
(($B=Uq',    // Set B to input split by ,
  g0)        // Get the first date and parse
-            // Subtract...
$A(          // Parse this date...
   $Bg1      // Get's second date
))/864e5     // Divides by 86,400,000
\$\endgroup\$
2
\$\begingroup\$

MATLAB, 41 31 bytes

disp(-diff(datenum(input(''))))
{'2015-12-03', '2014-12-22'}
   346  

Input must be a comma-separated cell array. datenum converts the input cell into a 2x1 numeric array with the time stamp. diff takes the difference between the two.


Old solution, 41 bytes:

disp(-diff(datenum(strsplit(input('')))))

Input must be a comma-separated string:

disp(-diff(datenum(strsplit(input('')))))
'2015-12-03, 2014-12-22'
   346

The curious ways of programming. This works because of MATLAB's implicit casting between datatypes.

The output from strsplit(input('')) is a cell of strings. You cannot use diff on a cell, but fortunately, datenum works, and it actually casts the cell input back to a 2x1 numeric array, making diff possible to use.

You can specify a whole lot of delimiters in strsplit, but comma is the default one. Also, the default input to datenum is on the format yyyy-mm-dd. For those reasons, a lot of specifications such as: datenum(s,'yyyy-mm-dd') are avoided, saving a whole lot of bytes.

For the record, this would be 21 bytes if I could use a function:

@(s)-diff(datenum(s))
\$\endgroup\$
  • 1
    \$\begingroup\$ How could I forget about diff... Might as well just delete my submission, because it's essentially the same, but with 2 calls to datenum instead. \$\endgroup\$ – slvrbld Dec 8 '15 at 9:15
  • 1
    \$\begingroup\$ Great choice of input format! \$\endgroup\$ – Luis Mendo Dec 9 '15 at 13:09
2
\$\begingroup\$

Javascript ES6, 63 bytes

Tested in chrome.

alert(((p=Date.parse)((a=prompt().split`,`)[0])-p(a[1]))/864e5)
\$\endgroup\$
  • \$\begingroup\$ comma-seperated from the question \$\endgroup\$ – ev3commander Dec 8 '15 at 2:22
  • \$\begingroup\$ @ev3commander Yes, I just fixed that. \$\endgroup\$ – SuperJedi224 Dec 8 '15 at 2:22
  • 2
    \$\begingroup\$ @SuperJedi224 Huh. Firefox gives Invalid date, whilst chrome happily proceeds. \$\endgroup\$ – Conor O'Brien Dec 8 '15 at 3:45
  • 5
    \$\begingroup\$ I'd mark this Chrome-specific as it only seems to work in chrome. I think the compliant way would be to use Date.parse and replace the - with / \$\endgroup\$ – Downgoat Dec 8 '15 at 3:58
  • 1
    \$\begingroup\$ Most browsers require the date to be padded so 2015-12-03 will work but 2015-12-3 will not (except in Chrome). The question does say that the date will be in the format YYYY-MM-DD so if the input really did follow that it would be cross-browser compatible, however the examples seem to say otherwise. Anyway, you could use Date.parse instead of new Date to save 2 bytes: alert((p((a=prompt(p=Date.parse).split`,`)[0])-p(a[1]))/864e5) \$\endgroup\$ – user81655 Dec 8 '15 at 4:32
2
\$\begingroup\$

PHP, 63 64 77 bytes

Found that the classic approach is shorter than the OOP one:

$x=fgetcsv(STDIN);$s=strtotime;echo($s($x[0])-$s($x[1]))/86400;

Reads the comma separated string from STDIN.


The straight forward OOP way (77 bytes):

$x=fgetcsv(STDIN);echo(new DateTime($x[0]))->diff(new DateTime($x[1]))->days;

Edits

  • Saved 13 bytes by using strtotime instead of DateTime.
  • Saved 1 byte by storing strtotime in a variable. Thanks to Blackhole.
\$\endgroup\$
  • \$\begingroup\$ -3 bytes: move the assignments to their first usage in parentheses (-1 byte each) and You can use <?= instead of echo. \$\endgroup\$ – Titus Dec 21 '16 at 16:33
1
\$\begingroup\$

VBA, 69 bytes

Function x(s)
g=Split(s, ",")
x=CDate(g(0))-CDate(g(1))
End Function
\$\endgroup\$
1
\$\begingroup\$

psql, 75 bytes

(74 characters code + 1 character command line option)

\prompt i
select split_part(:'i',',',1)::date-split_part(:'i',',',2)::date

psql is PostgreSQL's interactive terminal. To respect the “Each submission must be a full program.” rule, the code reads the input itself.

Sample run:

bash-4.3$ psql -tf how-long-was-this.sql <<< '2015-12-3,2013-12-3'
      730
\$\endgroup\$
1
\$\begingroup\$

MATL, 5 bytes

iPYOd

This is the same as StewieGriffin's answer, except I used flip then diff rather than diff then negating the result.

Full explanation, with corresponding Matlab functions:

i   %// input(''), get input
P   %// flip, flips the array
YO  %// datenum, converts date string into an integer
d   %// diff, finds the difference between dates
\$\endgroup\$
  • 2
    \$\begingroup\$ Note: Whilst MATL was only released on December 12, after this challenge was posted, I came up with this answer on December 9 using a pre-release MATL compiler, which is almost identical to the released compiler, this code is the same. \$\endgroup\$ – David Dec 13 '15 at 23:54
  • 2
    \$\begingroup\$ Also, this is in no way an endorsement of the popular Apple portable music device :P \$\endgroup\$ – David Dec 13 '15 at 23:54
  • 1
    \$\begingroup\$ I should have used o for the datenum function :-D \$\endgroup\$ – Luis Mendo Dec 13 '15 at 23:55
  • \$\begingroup\$ That would have been amazing! \$\endgroup\$ – David Dec 13 '15 at 23:55
  • 1
    \$\begingroup\$ @ev3commander most answers on PPCG are the same as other answers, especially in cases like this where 4 commands suffice. \$\endgroup\$ – David Dec 14 '15 at 21:32
1
\$\begingroup\$

PowerShell v2+, 50 44 Bytes

$a,$b=$args-split','|%{date $_};($a-$b).Days

Takes input argument as a string, splits it on the comma, then pipes the array via a built-in alias date short for Get-Date to convert our strings into .NET datetime format. Those two dates then get stored simultaneously into $a and $b. We then use an overloaded-subtraction-operator to subtract the second from the first, and output the .Days thereof.

Golfed 6 bytes thanks to TessellatingHeckler.

Technically non-competing, as it doesn't have an online interpreter available, since the FOSS implementation of PowerShell, Pash, is around PowerShell v0.5. It doesn't support -split yet, let alone the complex .NET date functionality.

\$\endgroup\$
1
\$\begingroup\$

Excel, 25 bytes

=LEFT(A1,10)-RIGHT(A1,10)

Excel automatically handles the strings as dates.

\$\endgroup\$
0
\$\begingroup\$

Jolf, 33 bytes

Only works in Chrome. Noncompeting, since language updates postdate question. I'll add a more thorough explanation later.

$S=$viGi', mDN~DH r}/m4SmeP"864"5

“Explanation”

$S=$viGi', mDN~DH r}
$S=$                 sets S equal to
    viGi',           take string input and reassign it to the comma-split input
           mD      } map with this function 
             N~DH r  return the time of the date of H (element)

/m4SmeP"864"5
/             divide
 m4S           subtraction applied to S (S[0] - S[1])
    meP"864"5  and 864 * 10 ^ 5 (thanks to Super Jedi for his nice constant)
              implicit output
\$\endgroup\$
  • \$\begingroup\$ How about you put "noncompeting" in your header? \$\endgroup\$ – ev3commander Dec 24 '15 at 13:29
0
\$\begingroup\$

MATLAB, 59 bytes

s=strsplit(input(''),',');disp(datenum(s{1})-datenum(s{2}))

Very straightforward approach: input has to be given as a string from the command window. The input string is then split and the number of days between the dates (and nothing else) is calculated from the serial date numbers. I'm quite sure there is a way to avoid the need for calling datenum twice though...

\$\endgroup\$
0
\$\begingroup\$

Python 2, 109 113 bytes

import datetime as d 
j=[d.date(*[int(k) for k in g.split('-')]) for g in raw_input().split(',')]
print j[0]-j[1]
\$\endgroup\$
0
\$\begingroup\$

T-SQL + SQLCMD, 51 bytes

PRINT DATEDIFF(D,RIGHT('$(i)',10),LEFT('$(i)',10))

Tested with SQL Server 2008R2. The $(i) is replaced with the input provided as a command line argument.

Sample run:

sqlcmd -i script.sql -v i="2015-12-08,2016-01-01"
-24
\$\endgroup\$
0
\$\begingroup\$

Mathematica, 61 bytes

Print@First[#-#2&@@DateObject/@InputString[]~StringSplit~","]

Basic date subtraction.

\$\endgroup\$
0
\$\begingroup\$

Perl, 91 86 + 2 for np flags, 88 bytes

use Date::Calc qw(Delta_Days);($a,$b)=split(/,/);$_=Delta_Days(split(/-/,$b),split(/-/,$a))

use Date::Parse;$_=str2time((split(/,/,$_))[0])-str2time((split(/,/,$_))[1]);$_/=86400

Example

$ echo 2015-12-3,2015-12-1 | perl -npe 'use Date::Parse;$_=str2time((split(/,/,$_))[0])-str2time((split(/,/,$_))[1]);$_/=86400'
2
\$\endgroup\$
0
\$\begingroup\$

jq, 50 bytes

(49 characters code + 1 character command line option)

./","|map(.+"T0:0:0Z"|fromdate)|(.[0]-.[1])/86400

Sample run:

bash-4.3$ ~/bin/jq -R './","|map(.+"T0:0:0Z"|fromdate)|(.[0]-.[1])/86400' <<< '2015-12-3,2013-12-3'
730

On-line test (Passing -R through URL is not supported – so input passed as string "2015-12-3,2013-12-3".)

\$\endgroup\$
0
\$\begingroup\$

Mathematica, 56 bytes

Print@#&@@-DateDifference@@InputString[]~StringSplit~","

Most (all?) date functions will try to parse string inputs into dates automatically.

\$\endgroup\$
0
\$\begingroup\$

Japt, 13 bytes

£ÐXÃr- zHÑ7e5

Try it

\$\endgroup\$
0
\$\begingroup\$

C# .NET, 148 bytes

using System;class P{static void Main(string[]a){Console.Write((DateTime.Parse(a[0].Substring(11,10))-DateTime.Parse(a[0].Substring(0,10))).Days);}}

Try Online

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.