35
\$\begingroup\$

Challenge

Given that Christmas is:

  • December
  • Month 12
  • Day 25

Every year, determine today's date, and whether or not today is Christmas. If it is Christmas, you must print "It's Christmas". If it is not Christmas, you must somehow wait until Christmas and then print "It's Christmas".

Example

From this Stack Overflow Question

import time
while time.strftime("%b, %d", time.localtime()) != "Dec, 25":
    time.sleep(60)
print "It's Christmas"

Python in 115 Characters

Rules

Here are the rules:

  • Assume that the computer's clock is always right.
  • Your code must be able to be started at any time.
  • Your code must print "It's Christmas" on Christmas.
  • Looping is certainly not necessary, but once started your code should not stop until it has printed.
  • Shortest code wins.
\$\endgroup\$
1
  • \$\begingroup\$ I thought the input is in Julian date before I read this post \$\endgroup\$
    – Ming-Tang
    Dec 21, 2011 at 9:51

38 Answers 38

30
\$\begingroup\$

Unix, 39 bytes

echo{,} "It\'s christmas"|at -t12252359

With help from Dennis, thanks for that.

\$\endgroup\$
4
  • \$\begingroup\$ This violates »Looping is certainly not necessary, but once started your code should not stop until it has printed.«, though. \$\endgroup\$
    – Joey
    Dec 7, 2013 at 17:59
  • \$\begingroup\$ I don't understand your critique. Do you claim this is looping? That it stops before printing? \$\endgroup\$ Dec 7, 2013 at 19:30
  • 2
    \$\begingroup\$ Using echo{,} "It\'s Christmas"|at -t12252359, this is shorter than the accepted answer. (The backslash is required by the way.) \$\endgroup\$
    – Dennis
    Jun 6, 2015 at 5:18
  • 1
    \$\begingroup\$ @Dennis: Nice use of brace expansion. \$\endgroup\$
    – Joey Adams
    Jun 9, 2015 at 12:45
18
\$\begingroup\$

Perl + Unix, 40 chars

1until`date`=~/c 25/;say"It's Christmas"

This is the same as J B's Perl solution, except that I save a few chars by using the external date command instead of Perl's localtime.

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

PowerShell, 45 46 chars

for(;(date).date-ne'12/25'){}"It's Christmas"

It's certainly not very power-efficient, so a laptop battery might die before Christmas (reason to wish for a new one, maybe). But not sleeping is definitely shorter.

This is also locale-agnostic. And thanks to Jaykul for a nice trick in reducing this further.

Abusing the rules a bit, 45 chars

for(){"It's Christmas"*((date)-like'12/25*')}

This will print empty lines until it's Christmas, upon which it will print “It's Christmas”.

It ...

  • ... can be started at any time.
  • ... prints “It's Christmas” on Christmas. Several times. The whole day long. (The rules didn't say anything about how often it may be printed.)
  • ... does not print “It's Christmas” on not-Christmas (although it prints an empty line in that case; can be rectified by sacrificing another character, but then this gains nothing over the more sane solution above).
  • ... does not ever stop (not even after it has printed “It's Christmas” but definitely not before).
\$\endgroup\$
5
  • 2
    \$\begingroup\$ for(;(date).date-ne"12/25"){}"It's Christmas" # 45 chars \$\endgroup\$
    – Jaykul
    Dec 6, 2011 at 6:32
  • \$\begingroup\$ Jaykul: Thanks ... that's something I never would have thought to be working. \$\endgroup\$
    – Joey
    Dec 6, 2011 at 9:54
  • \$\begingroup\$ The "abusive" script could also use -match, and do without the wildcard, for no gain/loss in characters. \$\endgroup\$
    – Iszi
    Dec 7, 2013 at 7:38
  • \$\begingroup\$ You can remove the abuse now, it's unneeded. \$\endgroup\$ Sep 11, 2016 at 13:55
  • \$\begingroup\$ @EriktheGolfer: How so? It still offers an interesting alternative approach, even though it's not shorter. \$\endgroup\$
    – Joey
    Sep 11, 2016 at 14:35
12
\$\begingroup\$

PostScript, 90

(%Calendar%)currentdevparams begin{Month 12 eq Day 25 eq and{exit}if}loop(It's Christmas)=

Don't run on a printer, it doesn't print a page, and it will only DoS your printer until Christmas day. Then again, getting your printer back would be a nice present.

\$\endgroup\$
2
  • 4
    \$\begingroup\$ Don't forget to tape a sign to the printer saying: DO NOT KILL JOB UNTIL CHRISTMAS! \$\endgroup\$
    – Joey Adams
    Dec 6, 2011 at 16:58
  • \$\begingroup\$ I guess most printers won't even have a working hardware clock as that's an optional feature. Very nice, though :) \$\endgroup\$
    – Joey
    Dec 7, 2011 at 9:38
7
\$\begingroup\$

Mathematica, 47

While[Date[][[2;;3]]!={12,25}];"It's Christmas"
\$\endgroup\$
1
  • \$\begingroup\$ I was surprised that Mathematica doesn't have a built-in for Xmas. \$\endgroup\$ Aug 14, 2023 at 17:51
5
\$\begingroup\$

Perl, 44 45

perl -E'1until localtime=~/c 25/;say"It's Christmas"'

Wouldn't GMT time be sufficient? (3 characters off ;-)

\$\endgroup\$
4
  • \$\begingroup\$ 1until localtime=~/c 25/; would save you one char. :) \$\endgroup\$ Dec 5, 2011 at 15:33
  • \$\begingroup\$ I thought I'd already tried that and it failed, but it turns out I actually forgot -E at the time. Thanks! \$\endgroup\$
    – J B
    Dec 5, 2011 at 15:49
  • \$\begingroup\$ No problem. (Ps. I just posted a version of your solution using backticks instead of localtime below. Feel free to steal it if you like, but I felt the extra dependency justified a separate answer.) \$\endgroup\$ Dec 5, 2011 at 15:59
  • \$\begingroup\$ Naaaw, shame's on me for not thinking of it again. The separate answer is perfectly justified IMO (and upvoted). \$\endgroup\$
    – J B
    Dec 6, 2011 at 8:54
5
\$\begingroup\$

Perl, 45

{localtime=~/c 25/&&die"It's Christmas";redo}

Perl, 44

using ternary operator (Thanks to Ilmari Karonen).

{localtime=~/c 25/?say"It's Christmas":redo}
\$\endgroup\$
4
  • \$\begingroup\$ ? : instead of && ; would save you one char too. (And I'd use say instead of die for prettier output.) \$\endgroup\$ Dec 5, 2011 at 15:35
  • \$\begingroup\$ @Ilmari Karonen: thanks. But by using say instead of die, the script never finish. \$\endgroup\$
    – Toto
    Dec 5, 2011 at 15:43
  • \$\begingroup\$ It will, if you use the ternary operator. \$\endgroup\$ Dec 5, 2011 at 15:49
  • \$\begingroup\$ @Ilmari Karonen: yes, of course. May be i'm too tired !!! \$\endgroup\$
    – Toto
    Dec 5, 2011 at 16:01
5
\$\begingroup\$

Javascript, 51 chars

It's a CPU killer:

while(!/c 25/.test(Date()));alert("It's Christmas")
\$\endgroup\$
5
\$\begingroup\$

R (47)

while(!grepl("c 25",date())){};"It's Christmas"
\$\endgroup\$
1
  • 1
    \$\begingroup\$ while(!grepl("c 25",date()))0;"It's Christmas" is 1 byte shorter. \$\endgroup\$ Jan 9, 2020 at 11:23
4
\$\begingroup\$

I wanted to do this without parsing strings. Subsequently, there's a lot of magic numbers in my code.

I did some approximation to account for leap years. No one said that it had to print it out right on 00:00:00, Dec. 25!

Perl, 80 69 57 characters

{(time-30931200)%31557600<86399?die"It's Christmas":redo}

Edited for more concise looping!

\$\endgroup\$
3
\$\begingroup\$

Python, 66 68

import time
while'c 25'not in time.ctime():1
print"It's Christmas"
\$\endgroup\$
5
  • \$\begingroup\$ That 1 at the end of the second line looks quite suspicious to me. :P \$\endgroup\$
    – cjfaure
    Jan 7, 2014 at 15:10
  • \$\begingroup\$ @Trimsty: The 1 provides a body for the while-loop. It's basically a busy wait until December 25. It has the similar effect to while 1:if'c 25'in time.asctime():break. \$\endgroup\$ Jan 7, 2014 at 15:39
  • \$\begingroup\$ Ah, okay, thanks for clearing that up. \$\endgroup\$
    – cjfaure
    Jan 8, 2014 at 8:02
  • \$\begingroup\$ I think time.ctime() would do. \$\endgroup\$
    – gnibbler
    Feb 12, 2014 at 6:14
  • \$\begingroup\$ @gnibbler: Indeed it would. Nice catch. \$\endgroup\$ Feb 12, 2014 at 15:41
3
\$\begingroup\$

TI-BASIC, 42 38

Repeat 769=sum(getDate²,2
End
"It's Christmas

Expects the date format to be YYYY/MM/DD.

getDate creates a three-element list {year,month,day}; only on Christmas is month^2 + day^2 equal to 769.

23 bytes are used for the string because lowercase letters are two bytes each, except for i which is displayed as the imaginary unit token.

\$\endgroup\$
2
\$\begingroup\$

Batch file, 68 chars

:l
@date/t|findstr/c:"-12-25">nul&&echo It's Christmas&&exit
@goto l

Not usable interactively, as it kills the session. Solving that would require 5 more characters.

Also locale-sensitive. This works on my locale which uses ISO 8601 date format.

But hey, it's a batch file (by most not even regarded as a programming language). And shorter than Javascript (and on par with Python).

\$\endgroup\$
2
\$\begingroup\$

Groovy, 55

while(!new Date()==~/.*c 25.*/);
println"It's Christmas"

Think it works, but still waiting for output.

\$\endgroup\$
3
  • \$\begingroup\$ If Groovy's regexps are anything like in most other languages, those .* are entirely unnecessary. (Ps. You can test it by waiting for Dec 5 instead of 25.) \$\endgroup\$ Dec 5, 2011 at 18:54
  • 1
    \$\begingroup\$ Ilmari, Groovy is a JVM language and Java's regexes are anchored by default. \$\endgroup\$
    – Joey
    Dec 5, 2011 at 19:19
  • 1
    \$\begingroup\$ Ilmari, I'd check but my program is still running \$\endgroup\$
    – Armand
    Dec 6, 2011 at 16:56
2
\$\begingroup\$

(pdf)eTeX - 180 chars only December 1-25.

\lccode`m`~\let\e\expandafter\def~{\ifdim900pt<\pdfelapsedtime
sp\pdfresettimer\else\e~\fi}\lowercase\e{\e\scantokens\e
{\romannumeral\numexpr (25 - \day)*96000}}It's Christmas!\bye

TeX only has a way to access the date when the program starts, and the time elapsed since the start, capped at 32768 seconds, so I need to compute the number of seconds to wait, and for each second do a loop which waits for the elapsed time to reach 1s and reset the time. (Precisely, I'm doing blocks of 900 seconds.)

Working for any month requires more work: 355 chars.

\lccode`m=`~\let\o\or\let\y\year\let\n\numexpr\let\e\expandafter
\def\b#1{\ifnum#1=\n(#1/4)*4\relax+1\fi}\def~{\ifdim
900pt<\pdfelapsedtime sp\pdfresettimer\else\e~\fi}\lowercase
\e{\e\scantokens\e{\romannumeral\n(25-\day+\ifcase\month\o334\b\y
\o303\b\y\o275\o244\o214\o183\o153\o122\o91\o61\o30\o0\ifnum25<\day
365\b{\n\y+1}\fi\fi)*96000}}It's Christmas!\bye
\$\endgroup\$
2
\$\begingroup\$

MySQL, 180 chars

Because what are you using your database engine for, anyway?

DELIMITER $$
CREATE FUNCTION c() RETURNS CHAR(14) BEGIN a: LOOP IF DAY(NOW())=25 && MONTH(NOW())=12 THEN RETURN 'It\'s Christmas'; END IF; END LOOP a; END$$
DELIMITER ;
SELECT c();

Not very competitive lengthwise, but hey, it's doable!

\$\endgroup\$
1
  • \$\begingroup\$ Try DELIMITER /, RETURNS TEXT and CURDATE()LIKE'%12-25'; and try to remove some whitespace. \$\endgroup\$
    – Titus
    Apr 16, 2017 at 23:24
2
\$\begingroup\$

Ruby, 53

until Time.now.to_s=~/c 25/
end
puts"It's Christmas!"
\$\endgroup\$
2
\$\begingroup\$

PHP, 40 bytes

<?while(date(dm)-1225);?>It´s Christmas;

Loop until 25th of December; then exit to plain mode and print.

Run with default settings (don´t display notices).

\$\endgroup\$
2
\$\begingroup\$

8086 machine code, 33 bytes

00000000  b4 2a cd 21 81 fa 19 0c  75 f6 b4 09 ba 12 01 cd  |.*.!....u.......|
00000010  21 c3 49 74 27 73 20 43  68 72 69 73 74 6d 61 73  |!.It's Christmas|
00000020  24                                                |$|
00000021
\$\endgroup\$
2
\$\begingroup\$

Forth (gforth), 84 bytes

: f begin time&date drop 12 = 0<> swap 25 = 0<> and until s" It's Christmas!" type ;

Try it online!

Yet another stack language. Somehow not the longest answer.

The time&date word is very convenient here.

A stack overflow happens since time&date values are left on stack every iteration.

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

Javascript, 93 89 78 77 chars

function x(){Date().match("c 25")?alert("It's Christmas"):setTimeout(x,1)}x()

\$\endgroup\$
3
  • \$\begingroup\$ @Joey Thanks! I forgot about that. \$\endgroup\$
    – JiminP
    Dec 5, 2011 at 9:52
  • 2
    \$\begingroup\$ Another non-blocking version: setInterval('/c 25/.test(Date())&&alert("It\'s Christmas")',9) at 61 chars ... the only drawback is that it will alert() all day on Christmas. \$\endgroup\$ Dec 6, 2011 at 3:14
  • \$\begingroup\$ Why setInterval to 1? setInveral to 1000*60*60*24 and it both won't make the process suffer and will notify only once on christmas. \$\endgroup\$ Feb 12, 2014 at 20:24
1
\$\begingroup\$

D, 130

import std.datetime,std.stdio;
main(){
do{
auto t = Clock.currTime();
}while(t.month!=12||t.day!=25);
writeln("It's Christmas");
}
\$\endgroup\$
2
  • \$\begingroup\$ You can probably save two characters in the assignment. And a few more by reducing the number of lines. \$\endgroup\$
    – Joey
    Dec 5, 2011 at 16:28
  • \$\begingroup\$ I can also save some by using t.month^12|t.day^25 (if I get my priorities right) \$\endgroup\$ Dec 5, 2011 at 18:38
1
\$\begingroup\$

Q, 63 chars

system"t 1000";.z.ts:{$["12.25"~-5#-3!.z.d;1"It's Christmas";]}

will work for christmas day on every year

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

SQL*Plus + PL/SQL - 100

EXEC LOOP EXIT WHEN TO_CHAR(SYSDATE,'DDMM')='2512';END LOOP;DBMS_OUTPUT.put_line('It''s Christmas');
  • Assuming SERVEROUTPUT ON
  • Shorter then the MySql solution (eat that, MySql!)
  • Too late for last year, but in time for this year
  • Tried DBMS_OUTPUT.put instead of DBMS_OUTPUT.put_line but that doesn't print anything.
\$\endgroup\$
1
\$\begingroup\$

C# (126)

using System;class P{static void Main(){while(DateTime.Now.Date.ToString("Md")!="1225");Console.WriteLine("It's Christmas");}}

Nicer for your battery:

C# (163)

using s=System;class P{static void Main(){s.Threading.Thread.Sleep(s.DateTime.ParseExact("1225","Md",null)-s.DateTime.Now);s.Console.WriteLine("It's Christmas");}}

edit

The second ("nicer for your battery") version does have a bit of an issue dec. 26th to dec. 31st I just thought of :P

Both versions can probably be shortened a bit more.

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

VBA, 58 Bytes

Anonymous VBE immediates window function that takes no input and runs until it's Christmas day, at which time it outputs It's Christmas to the VBE immediates window.

While Left(Now,5)<>"12/25":DoEvents:Wend:?"It's Christmas"
\$\endgroup\$
1
\$\begingroup\$

SmileBASIC, 49 47 bytes

DTREAD OUT,M,D?"It's Christmas"*(M/D==.48)EXEC.

month/day will be 0.48 on December 25th.

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

05AB1E, 28 21 bytes

[že25Qžf12Q&#}”It'sŒÎ

Try it online!

Noncompeting, I suppose(Beats the other non-competing answer, ha).

My first 05AB1E answer.

-7 bytes from ovs.

Explanation

[že25Qžf12Q&#”It'sŒÎ
[                            start an infinite loop
 že                          push current day
   25                        25
     Q                       are they equal?
      žf                     push current month
        12                   12
          Q                  are they equal?
           &                 logical and
            #                break if both conditions are true
             ”It'sŒÎ         push "It's Christmas"
                             implicit output
\$\endgroup\$
4
  • \$\begingroup\$ This will not output It's Christmas is the execution is started on Christmas, since "It's Christmas is part of the loop and won't get executed if # breaks on the first iteration. This can be fixed by closing the loop after # with }. \$\endgroup\$
    – ovs
    Nov 12, 2020 at 10:57
  • \$\begingroup\$ And with the help of Kevin's tip on compression, the string literal can be shortened to ”It'sŒÎ. \$\endgroup\$
    – ovs
    Nov 12, 2020 at 11:00
  • \$\begingroup\$ @Shaggy It loops infinitely and breaks on christmas. When it breaks, it prints the value. I think it's correct. \$\endgroup\$
    – Razetime
    Nov 12, 2020 at 16:42
  • 1
    \$\begingroup\$ Sorry, @Razetime, missed the infinite loop at the start :\ \$\endgroup\$
    – Shaggy
    Nov 12, 2020 at 16:43
1
\$\begingroup\$

Japt, 27 bytes

Ks f"c 25" ?`It's CËItµs`:P

To test against today's date : Replace c 25 with this month's last letter (shorthand) + space + day of the month. Feb 02 == b 02

Try it online!

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

Thunno 2, 23 bytes

(kNkM,¿⁺P¿Q)’It's ñẈmas

Try it online!

Explanation

(kNkM,¿⁺P¿Q)’It's ñẈmas  '# Full program
(          )              # Loop until this returns false:
 kNkM,                    #   Push [current month, current day]
      ¿⁺P¿Q               #   Not equal to [12, 25]
            ’It's ñẈmas  '# Push "It's Christmas"
                          # Implicit output
\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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