How many days to Christmas?

Thought I'd share this code snippet I just worked out. Nothing new or especially amazing, but we are getting toward the time of year when less experienced forum members might start asking about date calculations.

#include <TimeLib.h>

...

  TimeElements christmasDay;
  christmasDay.Day = 25;
  christmasDay.Month = 12; 
  christmasDay.Year = CalendarYrToTm(year());
  time_t christmasDayTime = makeTime(christmasDay);
  if (christmasDayTime < now()) {
    christmasDay.Year++;
    christmasDayTime = makeTime(christmasDay);
  }
  int daysToChristmas = elapsedDays(christmasDayTime) - elapsedDays(now()) - 1;

Please feel free to suggest improvements.

Good.

“time of year when less experienced forum members might start asking about date calculations.”
Well, new people usually want a complete package that they can “visually learn from”. :wink:

You're welcome

If you're going to start talking about Christmas, I'm sure you've all seen this

#include <stdio.h>
main(t,_,a)
char *a;
{
return!0<t?t<3?main(-79,-13,a+main(-87,1-_,main(-86,0,a+1)+a)):
1,t<_?main(t+1,_,a):3,main(-94,-27+t,a)&&t==2?_<13?
main(2,_+1,"%s %d %d\n"):9:16:t<0?t<-72?main(_,t,
"@n'+,#'/*{}w+/w#cdnr/+,{}r/*de}+,/*{*+,/w{%+,/w#q#n+,/#{l+,/n{n+,/+#n+,/#\
;#q#n+,/+k#;*+,/'r :'d*'3,}{w+K w'K:'+}e#';dq#'l \
q#'+d'K#!/+k#;q#'r}eKK#}w'r}eKK{nl]'/#;#q#n'){)#}w'){){nl]'/+#n';d}rw' i;# \
){nl]!/n{n#'; r{#w'r nc{nl]'/#{l,+'K {rw' iK{;[{nl]'/w#q#n'wk nw' \
iwk{KK{nl]!/w{%'l##w#' i; :{nl]'/*{q#'ld;r'}{nlwb!/*de}'c \
;;{nl'-{}rw]'/+,}##'*}#nc,',#nw]'/+kd'+e}+;#'rdq#w! nr'/ ') }+}{rl#'{n' ')# \
}'+}##(!!/")
  :t<-50?_==*a?putchar(31[a]):main(-65,_,a+1):main((*a=='/')+t,_,a+1)
    :0<t?main(2,2,"%s"):*a=='/'||main(0,main(-61,*a,
"!ek;dc i@bK'(q)-[w]*%n+r3#l,{}:\nuwloca-O;m .vpbks,fxntdCeghiry"),a+1);
}

What the hell is that? Is that really valid C/C++? Good grief!

I do like a bit of obsfuscation.
My personal favourite

There are many different Christmas' and they are not all on Dec 25 and not just a single day.

Paul

I eschew obfuscation.

Output from the code in reply#3 (no sh*t):

On the first day of Christmas my true love gave to me
a partridge in a pear tree.

On the second day of Christmas my true love gave to me
two turtle doves
and a partridge in a pear tree.

On the third day of Christmas my true love gave to me
three french hens, two turtle doves
and a partridge in a pear tree.

On the fourth day of Christmas my true love gave to me
four calling birds, three french hens, two turtle doves
and a partridge in a pear tree.

On the fifth day of Christmas my true love gave to me
five gold rings;
four calling birds, three french hens, two turtle doves
and a partridge in a pear tree.

On the sixth day of Christmas my true love gave to me
six geese a-laying, five gold rings;
four calling birds, three french hens, two turtle doves
and a partridge in a pear tree.

On the seventh day of Christmas my true love gave to me
seven swans a-swimming,
six geese a-laying, five gold rings;
four calling birds, three french hens, two turtle doves
and a partridge in a pear tree.

On the eigth day of Christmas my true love gave to me
eight maids a-milking, seven swans a-swimming,
six geese a-laying, five gold rings;
four calling birds, three french hens, two turtle doves
and a partridge in a pear tree.

On the ninth day of Christmas my true love gave to me
nine ladies dancing, eight maids a-milking, seven swans a-swimming,
six geese a-laying, five gold rings;
four calling birds, three french hens, two turtle doves
and a partridge in a pear tree.

On the tenth day of Christmas my true love gave to me
ten lords a-leaping,
nine ladies dancing, eight maids a-milking, seven swans a-swimming,
six geese a-laying, five gold rings;
four calling birds, three french hens, two turtle doves
and a partridge in a pear tree.

On the eleventh day of Christmas my true love gave to me
eleven pipers piping, ten lords a-leaping,
nine ladies dancing, eight maids a-milking, seven swans a-swimming,
six geese a-laying, five gold rings;
four calling birds, three french hens, two turtle doves
and a partridge in a pear tree.

On the twelfth day of Christmas my true love gave to me
twelve drummers drumming, eleven pipers piping, ten lords a-leaping,
nine ladies dancing, eight maids a-milking, seven swans a-swimming,
six geese a-laying, five gold rings;
four calling birds, three french hens, two turtle doves
and a partridge in a pear tree.

Process returned 9 (0x9) execution time : 0.780 s
Press any key to continue.

PaulRB:

  int daysToChristmas = elapsedDays(christmasDayTime) - elapsedDays(now()) - 1;

Why the -1 at the end?

I take it that, on Christmas Eve, you want this to show 0 rather than 1 ?

Also, if you look at the rest of the code as you have it, I'm guessing that on Christmas Day itself, you will get either 364 or 365.

That's a good question. I found that without the -1, the answer came out 1 day too many. I put that down to the elapsedDays() macro truncating the value of now(), as though it was exactly midnight and the whole of today was still ahead. But you are right, I want it to yield 1 on Christmas Eve, 0 on Christmas Day and 364/5 on Boxing Day.

So I might have to change it like this:

  if (elapsedDays(christmasDayTime) < elapsedDays(now())) {

so that on Christmas day, the < check is false and the year is not increased

PaulRB:
That's a good question. I found that without the -1, the answer came out 1 day too many. I put that down to the elapsedDays() macro truncating the value of now(), as though it was exactly midnight and the whole of today was still ahead.

It did not occur to you to try to investigate why the answer came out the way it did?

What happens at different times of day? What time of day does makeTime() default to? Are time zones somehow involved?

Or is your clock simply 1 day behind? (What day does it think today is?)

Perhaps the TimeLib library is bugged, or there is a compiler bug?

Are you sure that you did not simply miscount the days to Christmas, and therefore the -1 is unnecessary?

Yes it occurred to me to investigate. It occurs to me to investigate a lot of things. But I work for a living, have other responsibilities, and limited time for hobbies. I'll get to it eventually.

Time of day makes no difference, except perhaps around midnight. My clock is correct, set moments before from a UK NTP server pool. Like all NTP servers, it reports UTC but in the UK we are on BST at the moment.

I googled "how many days to Christmas" and added the -1 to make my code match that answer.

PaulRB:
I googled "how many days to Christmas" and added the -1 to make my code match that answer.

My guess is that the explanation has to do with time zones. Perhaps Google misidentified your time zone.
There probably is another technical explanation. I don't know.

I'm going to do the calculation myself.

Today is Tuesday, September 11.
As September has 30 days, it is now (30 - 11) = 19 days to the last day of September.
As October has 31 days, it is (19 + 31) = 50 days to the last day of October.
As November has 30 days, it is (50 + 30) = 80 days to the last day of November.
As Christmas Day is December 25, it is (80 + 25) = 105 days to Christmas Day.

Let's check this another way.
According to my wall calendar, today is Tuesday of Week 37, and Christmas Day this year (2018) falls on Tuesday of Week 52. Therefore, it is now (52 - 37) = 15 weeks to the day, or (15 * 7) = 105 days, until Christmas Day.

Also, according to my almanac, today (Sept. 11, 2018) is the 254th day of the year, and Christmas Day (Dec. 25) is the 359th day of the year. Subtracting 254 from 359 yields 105.

What number of days does your code give for today?

It says

The time is 18:38:13 on Tuesday 11 September

It's 105 days to Christmas!

I've got the time zone hard-coded to BST at the moment.

PaulRB:
It says

The time is 18:38:13 on Tuesday 11 September

It's 105 days to Christmas!

I've got the time zone hard-coded to BST at the moment.

And that's using the code with the -1 ?
If so, that is very, very, very strange.

From TimeLib.h:

#define dayOfWeek(_time_) ((((_time_) / SECS_PER_DAY + 4)  % DAYS_PER_WEEK)+1) // 1 = Sunday
#define elapsedDays(_time_) ((_time_) / SECS_PER_DAY) // this is number of days since Jan 1 1970

The TimeLib I am looking at is from: Time/TimeLib.h at master · PaulStoffregen/Time · GitHub
Is this where you got yours from, PaulRB ?

I have a feeling we may have hit upon a compiler bug.

Yes, that's the library. But before we get too excited, let me check my code again and post a short complete sketch that illustrates the issue (or realise my mistake in the process!).