Fthe formula is the same but the result is different

The difference between the calculator and Zig:

numday = 1 quantieme = 244
wn = (numDay + self.quantieme() + 5)/7 - (numDay/5);

calculator : 36 → correct
zig : 35 → error

I’ve been struggling for 2 weeks with the dates, with the university reference of “Nante” and ChatGPT

I found the algorithm for week 52 53 and 01
but in the middle the figures ??? de zig

In the calculations that I make with the net or with calculator the answer is correct ->36

to compensate I have to use @rem(1,5)

because, with @rem = 2, the formula automatically adjusts higher.
and say if (@rem(x,x) is == 1) wn += 1; → 36

Well, the correct result would be 35,514…, it’s debatable how to round this.
You should probably avoid the intermediate divisions and do a single division at the end:

a = 5 * (numDay + self.quantieme() + 5)
b = 7 * numDay
numerator = a - b
wn = numerator / 35

This would round down. If you want to round up, then do:

wn = (numerator + 34) / 35

So, you advise me to :

wn = ( 1+,244 +5) / 7;
wn -= (1/5);

bad

No, because that will perform integer division and still have the rounding issue you’re encountering.

@as(u32, 1) / @as(u32, 5) == 0

You’re working with integer types, when you should be working with rational or floating point types instead.

I’m going to redo the calculation
in float, but according to my tests the result is wrong

var wx: f32 = 0;
            const numDayx :f32 =  @floatFromInt(dayZeller(self));
            const q : f32 =  @floatFromInt(self.quantieme());
            wx =(numDayx + q + 5)/7 - (numDayx/5);
std.debug.print("{d}\n\r",.{wx });
            wx = @round(wx);
             std.debug.print("{d}\n\r",.{wx });
             wn = @intFromFloat(wx);

calulator linux = 36 Zig = 36

Tested it on the fly, and the result looks fine.

I’ll come back later and tell the others if it’s OK.

These are formulas inherited from “C” but common to python, JavaScript not tested in Rust (I don’t know the language).

Another wrong formula to find the number of the day

var zeller = @mod(self.day + ((13 * (m + 1)) / 5) + K + (K / 4) + (J / 4) + (5 * J), 7);

grr. It’s getting random, I’m losing my Latin

Could you clarify what you’re trying to calculate?
It seems that in the first post, you were trying to calculate the number of the week (from 1 to 53), given the number of the day (from 1 to 365). But what is the self.quantieme() and how does it differ from numDay?

Perhaps this is what you wanted:

fn week(day: u16) u16{
  // change from 1 to 0-based
  const d = day - 1; 

  //Rounded up integer division
  const numerator = d + 6;
  const week = @divFloor(numerator, 7);

  // Change it back to 1-based
  return w + 1;
}

With day = 245, it gives the correct week number 36.

I think it would be helpful if you could provide a reference for what you’re trying to calculate (as @LucasSantos91 suggested) and perhaps some tests showing the desired result and what you’re actually getting.

However, I did a quick search for “Zeller”, and I think this is what you’re trying to use: Zeller's congruence - Wikipedia The issue I see is that you’re using the wrong formula: the one with + 5J is under the “implementations in software” section with the note:

Unfortunately, in the truncating way most computer languages implement the remainder function, −2 mod 7 returns a result of −2. So, to implement Zeller’s congruence on a computer, the formulas should be altered slightly to ensure a positive numerator.

But you’re using @mod in your implementation, which is the mathematical modulo operator, so you should actually be using the original - 2J formula (or use @rem instead). Edit: actually, on second thought, this shouldn’t matter, since the difference 7J between the formulas is congruent to 0 mod 7… but I think the distinction between @mod and @rem is still worth bearing in mind.

  • @mod - mathematical modulo operation (example from the langref: @mod(-5, 3) == 1)
  • @rem - “traditional” C programmer’s % operation (example from the langref: @rem(-5, 3) == -2)
2 Likes

formule :

// Calcul standard du numéro de semaine Standard calculation of week number 
        var wn = (nd + self.quantieme() + 5) / 7 - (nd / 5);

Hello, first of all thank you for taking the time to answer, indeed, it is a formula that can be found either at the university, or on ChatGPT, or in the date processing for the 52 / 53 week or week number.
I’ve chosen the Representation of Dates and Times standard (referred to as ISO 8601:1988) standard because I’ve never had a problem constructing a date with the timestamp, it’s to solve a problem like making a calendar that can be used in business, I’ve done it on AS400 … Well, even though I’m retired, I’m trying to reproduce an environment based on the As400 mode.

this model where everything is f32 does not respond correctly to find week zero

but I use this model once I have found week zero

@trunc((numDay + Q + 5) / 7 - (numDay / 5));

To recover 52 … because it only gives me the 52 week the formula is designed to calculate standard weeks.

but when I check sometimes I have drifts with the basic formula var wn = (nd + self.quantieme() + 5) / 7 - (nd / 5);
to recover week zero where everything is integer , I know I’m not simple …

I use “deepl” as a translator
thanks

very bad :

   //--------------------------------
    //  Internal complex function
    //--------------------------------
    // Calculation of day number with Sunday = 0, Monday = 1...
    fn dayZeller(self :DATE) usize {
        const y: u32 = self.year - 1 ;
        var val  = (y * 365 + (y / 4) - (y / 100) + (y / 400));
        val  += DAYS_BEFORE_MONTH[self.month - 1];
        if (self.month > 2 and isLeapYear(self.year)) val += 1;
        val += self.day;
        val = val % 7;
        return val;
    }


    fn searchWeek(self: DATE) usize {
        // quantieme of Day
        const Q = quantieme(self);
        std.debug.print("{d}\t",.{Q});

        // N° Day
        const J : usize = dayZeller(self);
        std.debug.print("{d}\t",.{J});

        // N° week
        var wn : usize = 0;

        if ( J >= 0 and J < 5) {
            wn = ((J + Q + 5) / 7) - (J / 5);
        }
        else {
            wn = ((J + Q + 5) / 7) - (J / 5);

            if (wn > 0 ) wn -= 1;
        }

        // std.debug.print("{d}",.{wn});
        return wn; 
    }


DATE struct { year, month , day}

result :

1	3	getWeekday( Mercredi 01 Janvier 2025)  week:1
2	4	getWeekday( Jeudi 02 Janvier 2025)  week:1
3	5	getWeekday( Vendredi 03 Janvier 2025)  week:0
4	6	getWeekday( Samedi 04 Janvier 2025)  week:0
5	0	getWeekday( Dimanche 05 Janvier 2025)  week:1
6	1	getWeekday( Lundi 06 Janvier 2025)  week:1
7	2	getWeekday( Mardi 07 Janvier 2025)  week:2
8	3	getWeekday( Mercredi 08 Janvier 2025)  week:2
9	4	getWeekday( Jeudi 09 Janvier 2025)  week:2
10	5	getWeekday( Vendredi 10 Janvier 2025)  week:0
11	6	getWeekday( Samedi 11 Janvier 2025)  week:1
12	0	getWeekday( Dimanche 12 Janvier 2025)  week:2
13	1	getWeekday( Lundi 13 Janvier 2025)  week:2
14	2	getWeekday( Mardi 14 Janvier 2025)  week:3
15	3	getWeekday( Mercredi 15 Janvier 2025)  week:3
16	4	getWeekday( Jeudi 16 Janvier 2025)  week:3
17	5	getWeekday( Vendredi 17 Janvier 2025)  week:1
18	6	getWeekday( Samedi 18 Janvier 2025)  week:2
19	0	getWeekday( Dimanche 19 Janvier 2025)  week:3
20	1	getWeekday( Lundi 20 Janvier 2025)  week:3
21	2	getWeekday( Mardi 21 Janvier 2025)  week:4
22	3	getWeekday( Mercredi 22 Janvier 2025)  week:4
23	4	getWeekday( Jeudi 23 Janvier 2025)  week:4
24	5	getWeekday( Vendredi 24 Janvier 2025)  week:2
25	6	getWeekday( Samedi 25 Janvier 2025)  week:3
26	0	getWeekday( Dimanche 26 Janvier 2025)  week:4
27	1	getWeekday( Lundi 27 Janvier 2025)  week:4
28	2	getWeekday( Mardi 28 Janvier 2025)  week:5
29	3	getWeekday( Mercredi 29 Janvier 2025)  week:5
30	4	getWeekday( Jeudi 30 Janvier 2025)  week:5
31	5	getWeekday( Vendredi 31 Janvier 2025)  week:3



univ-lemans.fr/

jI found the right answer