Hỏi về cách tính thứ mấy, cho trước ngày tháng năm

int getDayNumber(int d, int m, int y) { //retuns the day number
	static int t[] = { 0, 3, 2, 5, 0, 3, 5, 1, 4, 6, 2, 4 };
	y -= m < 3;
	return (y + y / 4 - y / 100 + y / 400 + t[m - 1] + d) % 7;
}

char *getName(int day) { //returns the name of the day
	switch (day) {
	case 0:return("Sunday");
	case 1:return("Monday");
	case 2:return("Tuesday");
	case 3:return("Wednesday");
	case 4:return("Thursday");
	case 5:return("Friday");
	case 6:return("Saturday");
	default:return("Error: Invalid Argument Passed");
	}
}

chào a/c
em muốn hỏi chỗ static int t[] = { 0, 3, 2, 5, 0, 3, 5, 1, 4, 6, 2, 4 }; 0 3 2 5 0…(vẫn biết là 1 năm có 12 tháng trong đó có 12 giá trị tượng trưng cho 12 tháng nhưng số liệu đó dựa vào gì mà có được ạ)
em cám ơn

Công thức Zeller thì phải chỉnh một chút mới tính đúng, nhưng không cần bảng.
Công thức Sakamoto chia năm ngay vào ngày 1 tháng 3 để ngày nhuận nằm ngay trước nó (kết thúc một chu kì). Hai phần được chia gồm số ngày từ 1 tháng 1 tới ngày 1 tháng {1 | 2} và số ngày từ 1 tháng [3…12] tới hết ngày 31 tháng 12 năm hiện tính. Logic này để tránh phải chia trường hợp: nếu không trừ đi một ngày thì sẽ phải xét riêng những ngày của tháng 1 và 2 nếu năm y là năm nhuận.

Dễ thấy 0 mod 7 = 0 và 31 mod 7 = 3, là hai tháng đầu. 59 - 365 = 3 - 1 = 2 (mod 7). Tháng tư thì cộng thêm 31 ngày của tháng 3 nữa là ra, cho đến tháng 12 là xong.

Kiểm tra: Ngày 0 tới 364 là đủ 365 ngày, vậy ngày đầu năm (không nhuận) và cuối năm phải có cùng thứ. Thêm 1 ngày thì thứ phải đôn lên.

Ghi chú: thực ra phải là 58 - 364 cho nó thống nhất với ngày đầu tiên đánh số 0.

3 Likes

em cảm ơn a.
mà sao em search thêm tài liệu Sakamoto không tìm thấy ạ


Mặc định thì dùng thuật toán nào cũng được, mình thấy thuật Zeller hay được sử dụng,

2 Likes

cám ơn anh rất nhiều ! đây là thứ e tìm kiếm nhưng chả biết search ntn

83% thành viên diễn đàn không hỏi bài tập, còn bạn thì sao?