g | x | w | all
Bytes Lang Time Link
185Setanta240720T204031Zbb94
104Bash using only builtins240720T150100ZMartin K
087Lua231118T123135Zbluswimm
067Bash +GNU date181226T144652ZNahuel F
091Julia 1.0221116T223248ZAshlin H
178Go231116T145547Zbigyihsu
038Japt S221117T130504ZShaggy
060jq jn221117T162346Zpmf
08105AB1E190103T123837ZKevin Cr
053q221117T052714Zcillianr
061Bash181226T183848Zuser4180
088TSQL181225T200049ZNeil
088JavaScript181225T235827Ztargumon
123Scala181227T131700ZV. Court
059Excel formula181225T133344ZRichard
118Lua181231T040823ZTae Hana
077JavaScript181229T202343ZVadim
091MATLAB181229T153920ZAnthony
113Scala181228T220841ZKjetil S
089C# Visual C# Interactive Compiler181225T075211Zdana
106Python 3181228T222936ZAlbert C
068Perl 5181228T192237ZKjetil S
1283Python 2181225T054249ZiBug
076Red181225T081945ZGalen Iv
066Groovy181225T145810Zbdkosher
067SmileBASIC181225T113752Z12Me21
063Windows PowerShell181226T124055Zbriantis
103Python 2181226T211258ZTriggern
047Perl 6181225T032035ZSean
108VBA Excel181226T234546ZBarranka
072R181225T015604Zngm
157C gcc181226T005101ZErikF
102MySQL181225T205503ZTitus
141C# Visual C# Interactive Compiler181225T043719ZGymhgy
061PHP181225T200114ZTitus
080Ruby181225T132605ZiBug
063APL Dyalog Unicode181225T084325ZAdá

Setanta, 199 185 bytes

Setanta doesn’t have any way to get the current date or time, so this is a function that takes a [year, month, day] list as an argument.

And yes, for some reason, | has higher precedence than & in Setanta.

gniomh(d){p:=[360,329,301,270,240,209,179,148,117,86,56,26]b:=d[0]+1m:=d[1]l:=d[2]c:=391-l y:=0ma m<12|l<26{y=m>2b-=1c=p[m-1]-l}toradh"Christmas"+" Eve"*(c-(y|b%4|(b%100<1&b%400)|0&1))}

Try it on try-setanta-ie

Bash using only built-ins, 104 bytes

x=$(printf %\*s $((365-$(printf '%(%-j)T' $((EPOCHSECONDS+32054400)))%366)));echo Christmas ${x//?/ Eve}

Try it online!

Expanded

x=$(
  printf %\*s $((
                  365 - $(
                           printf '%(%-j)T' \
                             $(( EPOCHSECONDS + (6+365)*24*60*60 ))
                         ) % 366
               ))
)
echo Christmas ${x//?/ Eve}

Try it online!

Logic

$EPOCHSECONDS is a Bash special variable that gives us the current time as seconds since 1-Jan-1970,00:00UTC.

printf '%(...)T' interprets its next parameter as such, and outputs it using the ... as a strftime() formatter (the same as GNU date).

In particular printf '%(%-j)T' gives us the day-of-the-year (1..366) of the given time.

However instead of using "now", we advance by 6 days, so that 26 Dec becomes day 1; we then advance by a further 365 days, effectively retarding by a day when the following year is a leap year.

At this point we have a number in the range 0...366; we need to treat 366 as 0, so we take mod 366 (%366).

We then subtract the resulting day number from 365 to get the count of days until Christmas.

We then use printf '%*s' count to generate a string with count spaces, and store that in the variable x.

Lastly, we replace every symbol in $x with the word Eve, and output the result prefaced by Christmas.

Separate challenge from just "Bash"

This answer does not compete on diminution with other Bash answers; avoidance of external commands makes it rather larger but also faster.

Lua, 87 bytes

w=io.write w'Christmas't=os.time()while os.date('%d%m',t)~='2512'do t=t+86400w' Eve'end

Try it online!

Bash +GNU date, 72, 73, 67 bytes

for((d=7;`date +%-j -d$d\day`-1;d++));{ x+=\ Eve;};echo Christmas$x

Try it online

Julia 1.0, 91 bytes

using Dates
t=today()
print(:Christmas," Eve"^~-(tonext(==((12,26))∘monthday,t)-t).value)

Try it online!

Go, 178 bytes

import(."time";."strings")
func f()string{n:=Now()
y:=n.Year()
if n.Month()>11&&n.Day()>25{y++}
return"Christmas"+Repeat(" Eve",int(Date(y,12,25,0,0,0,0,UTC).Sub(n).Hours())/24)}

Attempt This Online!

And a variant that takes a Time as input, 175 bytes:

import(."time";."strings")
func f(n Time)string{y:=n.Year()
if n.Month()>11&&n.Day()>25{y++}
return"Christmas"+Repeat(" Eve",int(Date(y,12,25,0,0,0,0,UTC).Sub(n).Hours())/24)}

Attempt This Online!

Japt -S, 39 38 bytes

Ð
f
@f1V° UζB©25¶Uf}a Æ"Eve"Ãi`CËItµs

Test it

Ð\nf\n@f1V° UζB©25¶Uf}a Æ"Eve"Ãi`CËItµs
Ð                                            :Create date object for current date
 \n                                          :Assign to variable U
   f                                         :Get date value of U
    \n                                       :Assign to variable V
      @                                      :Function taking an integer X as argument
       f1                                    :  Set the date of U to (modifies U)
         V°                                  :  V, postfix incremented
            UÎ                               :  0-based month value of modified U
              ¶                              :  Check equality with
               B                             :    11
                ©                            :  Logical AND with
                 25¶                         :  Check equality between 25 and
                    Uf                       :    Date value of modified U
                      }                      :End function
                       a                     :Return the first value of X>=0 that returns true
                         Æ                   :Map the range [0,result)
                          "Eve"              :  Literal string
                               Ã             :End map
                                i            :Prepend
                                 `CËItµs     :  Compressed string "Christmas"
                                             :Implicit output joined with spaces

jq -jn, 60 bytes

"Christmas",(now|while(gmtime[1:3]!=[11,25];.+86400)|" Eve")

Try it online!

05AB1E, 93 89 87 81 bytes

'ŒÎžfže«Ž9Ú.S©DΘžg+т‰0Kθ4ÖUi390že-X+ë®_i0ë•ΘÏF•º11£®ª₂+ā2QX*+13žf-.£Ože-]Fð'»ˆ}J™

Try it online or Try it online with an emulated self-specified date of 'today'.

Old 93 89 87 bytes approach that loops over the days one by one:

žežfžg)V'ŒÎ[Y¨JŽ9ÚQ#Y`т‰0Kθ4ÖUD<i\28X+ë<7%É31α}‹iY¬>0ëY1¾ǝDÅsD12‹i>1ë\1Dǝ¤>2}}ǝVð'»ˆ}J™

Try it online or Try it online with an emulated self-specified date of 'today'.

Explanation:

05AB1E doesn't have any builtins for dates, except for receiving the current year/month/day/hours/minutes/seconds/microseconds, so most bytes are used for manual calculations.

'ŒÎ           '# Push dictionary string "christmas"
žfže«          # Append the current month and current day together
        .S     # Compare it with
     Ž9Ú       # Compressed integer 1225
               # (1 if >1225; 0 if ==1225; -1 if <1225)
          ©    # Store this comparison in variable `®` (without popping)
D              # Duplicate it
 Θ             # Check if it's equal to 1 (1 if 1; 0 if 0 or -1)
  žf+          # Add the current year to it
     т‰0Kθ4Ö   # Check if this is a leap year:
     т‰        #  Divmod it by 100
       0K      #  Remove the 0s
         θ     #  Only leave the last item
          4Ö   #  Check if it's divisible by 4
            U  # Pop and store this is_leap_year in variable `X`
i              # If the comparison is 1:
 390že-        #  Push 390 minus the current day
               #  (390 is 31 for days in December and 259 for days of Christmas Day)
 X+            #  Add the is_leap_year check from variable `X`
ë®_i           # Else if the comparison is 0:
    0          #  Push 0
ë              # Else (the comparison is -1):
 •ΘÏF•         #  Push compressed integer 5254545
      º        #  Mirror it to 52545455454525
       11£     #  Only leave the first 11: 52545455454
          ®ª   #  Convert it to a list of digits, and append the -1:
               #   [5,2,5,4,5,4,5,5,4,5,4,-1]
            ₂+ #  Add 26 to each: [31,28,31,30,31,30,31,31,30,31,30,25]
 ā             #  Push a list in the range [1,length] (without popping):
               #   [1,2,3,4,5,6,7,8,9,10,11,12]
  2Q           #  Check which is equal to 2: [0,1,0,0,0,0,0,0,0,0,0,0]
    X*         #  Multiply each by the is_leap_year check of variable `X`
      +        #  Add the values at the same positions in the lists together
 13žf-         #  Push 13 minus the current month
      .£       #  Only leave that many items from the end of the list
        O      #  Sum them together
 že-           #  Subtract the current day
]              # Close the if-else statements
 F             # Loop that many times:
  ð            #  Push a space character " "
  '»ˆ         '#  Push dictionary string "eve"
 }J            # After the loop: join the entire stack together
   ™           # Titlecase each word
               # (after which the result is output implicitly)

žežfžg)V   # Get the current [day,month,year] and save it in variable `Y`
'ŒÎ       '# Push dictionary string "christmas"
[          # Start an infinite loop:
 Y¨J       #  Remove the year, and join the month and day together
       Q   #  Check if this is equal to
    Ž9Ú    #  Compressed integer 1225
        #  #   If this is truthy (thus it's December 25th): stop the infinite loop
 Y`т‰0Kθ4ÖUD<i\28X+ë<7%É31α}‹iY¬>0ëY1¾ǝDÅsD12‹i>1ë\1Dǝ¤>2}}ǝV
           #  Go to the next day, and set `Y` to it
 ð         #  Push a space " "
 '»ˆ      '#  Push dictionary string "eve"
}J         # After the infinite loop: join the entire stack together
  ™        # Titlecase each word
           # (after which the result is output implicitly)

See this 05AB1E answer of mine to understand the is_leap_year check.

See this 05AB1E answer of mine to understand how we go to the next day (with the second longer approach).

See this 05AB1E tip of mine (sections How to use the dictionary? and How to compress large integers?) to understand why '»ˆ is "eve"; 'ŒÎ is "christmas"; Ž9Ú is 1225; and •ΘÏF• is 5254545.

q, 53 bytes

"Christmas",(4*(not 12 25~`mm`dd$.z.d+)(1+)/0)#" Eve"

k, 50 bytes

"Christmas",(4*(~12 25~`mm`dd$.z.d+)(1+)/0)#" Eve"

Increment counter while the date is not Dec 25th, then take that number of copies of " Eve" and append to "Christmas".

Bash, 68 65 61 bytes

Golfed 4 bytes thanks to Nahuel Fouilleul by using `` command substitution and eval in place of sed e and xargs

echo Christmas `eval date\ -d{0..366}day\;|sed /c.25/Q\;cEve`

Try it online!

Inside the `` command substitution, we have

eval run the following string as shell commands

|sed upon which, call the following sed commands

All the required number of Eves are produced each on its own line. This output is captured in ``, and is subject to word splitting where words are split on newlines. Each word is fed as an argument to echo.

echo Christmas ...

Each argument to echo is printed by being separated by spaces, resulting in the desired output.

T-SQL, 92 88 bytes

PRINT'Christmas'+REPLICATE(' Eve',DATEDIFF(D,GETDATE(),STR(YEAR(GETDATE()+6))+'-12-25'))

Edit: Saved 4 bytes thanks to @BradC.

JavaScript, 135 131 121 92 88 bytes

My first (naïve) solution (135b):

t=new Date();n=new Date();n.setMonth(11);n.setDate(25);'Christmas'+' Eve'.repeat((n>=t?n-t:(n.setFullYear(n.getFullYear()+1)-t))/864e5)

It sets 2 dates: now and Xmas of this year. If the latter hasn't passed yet, it just diffs them, if it has passed, diffs to next year's Xmas. Uses either diffs for the number of repeats.

(Trying to) Think Outside the Box (131b):

i=0;f=_=>{t=new Date();if(t.getMonth()!=11||t.getDate()!=25){i++;setTimeout(f,864e5)}else{alert('Christmas'+' Eve'.repeat(i))}};f()

The challange specifies WHICH output is required when running the program on a given day, but doesn't specify WHEN to return it...

This will just 'sleep' for a day, increment a counter by 1, and repeat till it's Xmas in order to give the output.

Since JavaScript doesn't guarantee the 'sleep' time, the actual result might be off.

It is also ugly for using the alert function, which means wer'e actually not dealing with pure JavaScript, but with browser APIs as well (we can use console.log at the cost of 6 extra bytes).

A better approach (121b):

t=new Date();i=0;while(t.getMonth()!=11||t.getDate()!=25){t=new Date(t.valueOf()+864e5);i++};'Christmas'+' Eve'.repeat(i)

Starting from today, increment the date by a day until it's Xmas, then use that loop's counter for the number of repeats required.

Improving (including going through a minifier and using 12Me21's trick to shave extra 5b) (92b):

for(s='Christmas',t=new Date;t.getMonth()/t.getDate()-.44;)t=new Date(t*1+864e5),s+=' Eve';s

Final touches (88b):

for(s='Christmas',t=new Date;t.getMonth()/(d=t.getDate())-.44;t.setDate(d+1))s+=' Eve';s

Scala, 123 bytes

Thanks to ASCII-only's work.

print("Christmas")
var d=new java.util.Date
while(d.getMonth()<11||d.getDate()!=25){print(" Eve");d.setDate(d.getDate()+1)}

Try it online!

Scala + Joda-Time, 140 bytes

import org.joda.time._
var s="Christmas"
var d=DateTime.now
while(d!=d.withDate(d.year().get(),12,25)){d=d.plusDays(1);s+=" Eve"};println(s)

Does not run in TIO since it requires Joda-Time library.

Excel formula, 59 bytes

="Christmas"&REPT(" Eve",DATE(YEAR(NOW()+6),12,25)-TODAY())

Lua, 137 118 bytes.

118 bytes

t,d,month,day=os.time,os.date,1,-6year=d"%Y"+(d"%D">"12/25"and 2or 1)print("Christmas",d" Eve":rep(d("%j",t(_G)-t())))

137 bytes (previous)

t,d=os.time,os.date a=d"*t"a.year,a.month,a.day=a.year+(d"%m%d">"1225"and 1 or 0),12,25 print("Christmas",("Eve "):rep((t(a)-t())/86400))

It's worth noting that it doesn't work in LuaJIT (syntax error)

JavaScript, 86 77 bytes

Using REPL it would be

for(c='Christmas',d=new Date;!/c 25/.test(d);d=new Date(+d+864e5))c+=' Eve';c

Kudos to ASCII-only for -9 bytes

MATLAB, 91 bytes

n=datetime
x=datetime(year(n+6),12,25)
s='Christmas'
while days(x-n)>=1 n=n+1 s=[s,' Eve'] end

MATLAB Non-looper, 100 bytes

x=datenum(datetime(floor((now+5)/365.2425),12,25))
d=x-now
['Christmas' repmat(' Eve',1,min(d(d>=0)))]

Scala, 116 113 bytes

var d=new java.util.Date
print("Christmas")
while(!(""+d).contains("c 25")){print(" Eve");d.setDate(d.getDate+1)}

Try it online!

Where c 25 is short for Dec 25.

C# (Visual C# Interactive Compiler), 89 bytes

Write("Christmas");for(var t=DateTime.Now;$"{t:Md}"!="1225";t=t.AddDays(1))Write(" Eve");

Try it online!

-3 bytes thanks to @JeppeStigNielsen!

My strategy is pretty straightforward:

  1. Initialize a loop variable t to the current date
  2. Print Eve if t is not Christmas
  3. Add a day to t and repeat

I tried some fancier things, but this way required the fewest bytes.

Python 3, 106 Bytes

from datetime import*
d=date.today()
print("Christmas"+" Eve"*(date((d+timedelta(6)).year,12,25)-d).days)

Perl 5, 68 bytes

print"Christmas";print" Eve"while localtime($i++*86400+time)!~/c 25/

Try it online!

Where c 25 is short for Dec 25.

Python 2, 128 bytes / Python 3, 130 bytes

of course, two less bytes with Python 2

from datetime import date as D
T=D.today()
Y=T.year
a=(D(Y,12,25)-T).days
print("Christmas"+" Eve"*[a,(D(Y+1,12,25)-T).days][a<0])

Red, 89 86 84 78 76 bytes

-10 bytes thanks to ASCII-only!

does[a: now prin"Christmas"while[a/3 * 31 + a/4 <> 397][prin" Eve"a: a + 1]]

Try it online!

Groovy, 66 bytes

d=[]as Date
print'Christmas'+' Eve'*(new Date((d+6).year,11,25)-d)

Try it online!

Courtesy of @ASCII-only

SmileBASIC, 73 71 67 bytes

?"Christmas";
@L?" Eve"*(D!=P);
P=D
DTREAD OUT,M,D
IF M/D-.48GOTO@L

The program prints "Christmas", then prints " Eve" every time a day passes, until it is December 25th. (12/25 = 0.48)
May take up to a year to run.

Windows PowerShell, 67 64 63 bytes

for(;1225-'{0:Md}'-f(date|% *ys $i)){$i++}'Christmas'+' eve'*$i

Try it online!

Managed to shave off 3 bytes 4 bytes (thanks Cows quack) by using the -format operator instead of .ToString(), and then subtracting the date string from the numerical value 1225 instead of doing a comparison with -ne. The resulting integer will be interpreted as a boolean for the conditional where 0 (which will happen on Christmas) is interpreted as False (don't enter the loop), and any other value is interpreted as True (enter the loop).

Since the integer is on the left now, the date string will be converted to the integer and math will be done, as opposed to the previous version where the 1225 integer was converted to string for the comparison.

Original Version


Windows PowerShell, 67 bytes

for(;(date|% *ys $i|% tost* Md)-ne1225){$i++};'Christmas'+' eve'*$i

Try it online!

Using a for loop as a while loop basically, because it's shorter. In the loop condition we check the current date (date, a shortened form of Get-Date), piped to ForEach-Object's alias %, using the form that can invoke a method by wildcarded name; in this case the method is AddDays() on the DateTime object, and the value we give it is $i.

This gets piped to ForEach-Object again to invoke the ToString() method, with format string Md (month, then day, minimal digits since we don't care for what comes next). This string is then tested to see if it's not equal -ne to the number 1225, which will be converted to a string for the comparison, saving me the quotes.

This is why it doesn't matter that the months and days are single digits, it will never be ambiguous because there's no other day of the year that would stringify to 1225.

The loop continues until the string is 1225. At the beginning of the program, $i will be zero so it will be comparing today's date, and the loop will never execute, but for any other day $i gets incremented in the loop body, so that we will have a count of how many days until the next Christmas, automatically accounting for leap years and whether or not Christmas passed this year.

After the loop we just output the string Christmas concatenated with the result of multiplying the string eve times the value of $i (which, on Christmas day, will be 0, resulting in no eves).

Python 2, 111 103 bytes

from datetime import*
d=date.today()
print"Christmas"+" Eve"*(date((d+timedelta(6)).year,12,25)-d).days

Try it online!

Update inspired by Richard Crossley's answer.

Explanation:

from datetime import*
# get today as a date, so we don't have to worry about rounding errors due to time
d=date.today()
                              # get the year of the Christmas to compare to
                              # if the current date is after this year's Christmas, the 6 day offset will give the next year
                              # otherwise, returns this year
                              (d+timedelta(6)).year
                         # next Christmas minus the current date
                         date(.....................,12,25)-d
# Christmas, plus (number of days until next Christmas) " Eve"s
print"Christmas"+" Eve"*(...................................).days

Perl 6, 61 47 bytes

say 'Christmas'~' Eve'x(Date.today...^{.month==12&&.day==25})

say 'Christmas'~' Eve'x(Date.today...^/12\-25/)

Try it online!

-14 bytes (!) thanks to Jo King

Date.today ...^ /12\-25/ is the sequence of dates starting today and ending the day before Christmas. (The regular expression /12\-25/ is matched against the string representation of the dates.) The string " Eve" is replicated a number of times equal to the length of that sequence, and is output after the string "Christmas".

VBA (Excel), 108 bytes

Copy in a blank module. Prints to the Immediate window:

Sub X:s="Christmas":d=Now:For t=1 To (DateSerial(Year(d+6),12,25)-d):s=s &" Eve":Next:Debug.Print s:End Sub

Note: Using : instead of line breaks saves two bytes per line.

Notice that the VBA editor will insert additional spaces between keywords, operators, etc... and parenthesis after the Sub definition, but if you copy and paste this code it will work (I couldn't get rid of that space before the &).

Not bad for VBA (for once).

R, 112 106 72 bytes

Via @digEmAll and @J.Doe

x=Sys.Date()-1;cat('Christmas');while(!grepl('12-25',x<-x+1))cat(' Eve')

Try it online!

My original answer was prior to the clarification that the code was to take the date on which the code is run as input. It could be modified as above to save many bytes but I won't bother.

function(x,z=as.Date(paste0(strtoi(format(x,"%Y"))+0:1,"-12-25"))-x)cat("Christmas",rep("Eve",z[z>=0][1]))

Try it online!

Explanation: everyone's at church so I have time to do this. Extract the year, coerce to integer. Make vector of that year's Xmas and the next year's Xmas and subtract the input date to get a vector of two differences between the input date and those two Xmases.

Pick the non-negative one and cat "Christmas" with that many "Eves".

C (gcc), 157 bytes

I thought that I would be able to avoid including time.h but that just gave segment faults.

#include <time.h>
*t,u;f(){time(&u);t=localtime(&u);t[5]+=t[4]>10&t[3]>25;t[4]=11;t[3]=25;u-=mktime(t);printf("Christmas");for(u/=86400;u++;printf(" Eve"));}

Try it online!

MySQL, 102 bytes

pretty much the same as Neil´s T-SQL answer. There seems to be no shorter way in SQL.

select concat("Christmas",repeat(" Eve",datediff(concat(year(now()+interval 6 day),"-12-25"),now())));

Try it online.

C# (Visual C# Interactive Compiler), 141 bytes

var g=DateTime.Now;Write("Christmas"+string.Concat(Enumerable.Repeat(" Eve",(new DateTime(g.Year+(g.Day>25&g.Month>11?1:0),12,25)-g).Days)));

Try it online!

PHP, 61 bytes

Christmas<?for($t=time();date(md,$t+=86400)-1226;)echo" Eve";

Run with -n or try it online.

Ruby, 80 bytes

require'date'
t=Date.today
puts'Christmas'+' Eve'*(Date.new((t+6).year,12,25)-t)

Try it online!

Thanks to tsh for his idea

APL (Dyalog Unicode), 76 63 bytesSBCS

Full program. Assumes ⎕IO←0 (zero-indexing).

⎕CY'dfns'
'Christmas',' Eve'⍴⍨4×12 25⍳⍨⍉2↑1↓⍉date(⍳366)+days⎕TS

Try it online!

⎕CY'dfns'copy in the dfns library

⎕TS current time stamp as [year,month,day,hour,min,sec,ms]
days[c] find the number of days[n] since 1899-12-31 00:00:00.000
(⍳366) add the first 366 integers (0…365) to that
date[c] find the dates[n] that correspond to those numbers (366×7 table; one column per unit)
 transpose (7×366 table; one row per unit)
1↓ drop one row (the years)
2↑ take the first two rows (months and days)
12 25⍳⍨ find the index of the first Christmas
 multiply that by four
' Eve'⍴⍨ use that to reshape the character list
'Christmas ', append that to this

[c] code of that function
[n] notes for that function