Làm thế nào để tính ngày trong tuần cho RTC?


7

Tôi đang sử dụng MCP7940 RTC từ microchip, nó yêu cầu nhập ngày trong tuần như một phần của việc cập nhật RTC theo ngày. Vậy tôi nên tính ngày như thế nào trong tuần dựa trên ngày mà người dùng cung cấp?

Câu trả lời:


8

Nếu bạn muốn tự tính toán ngày trong tuần, đây là triển khai C của một phần của mô-đun Perl tôi đã viết khoảng 20 năm trước. Tôi thích thuật toán này vì nó không yêu cầu bất kỳ vòng lặp hoặc bảng độ dài tháng nào. Lưu ý rằng ints được giả sử là 32 bit.

/* Returns the number of days to the start of the specified year, taking leap
 * years into account, but not the shift from the Julian calendar to the
 * Gregorian calendar. Instead, it is as though the Gregorian calendar is
 * extrapolated back in time to a hypothetical "year zero".
 */
int leap (int year)
{
  return year*365 + (year/4) - (year/100) + (year/400);
}

/* Returns a number representing the number of days since March 1 in the
 * hypothetical year 0, not counting the change from the Julian calendar
 * to the Gregorian calendar that occured in the 16th century. This
 * algorithm is loosely based on a function known as "Zeller's Congruence".
 * This number MOD 7 gives the day of week, where 0 = Monday and 6 = Sunday.
 */
int zeller (int year, int month, int day)
{
  year += ((month+9)/12) - 1;
  month = (month+9) % 12;
  return leap (year) + month*30 + ((6*month+5)/10) + day + 1;
}

/* Returns the day of week (1=Monday, 7=Sunday) for a given date.
 */
int dow (int year, int month, int day)
{
  return (zeller (year, month, day) % 7) + 1;
}

Một bảng có số ngày từ ngày 1 tháng 3 đến ngày đầu tiên của tháng nhất định có thể sẽ nhỏ hơn và nhanh hơn mã để đánh giá công thức đã cho, đặc biệt nếu một người chỉ quan tâm đến ngày trong phạm vi 2000-2099.
supercat

@supercat: Tại sao bạn không cho chúng tôi xem mã đó sẽ trông như thế nào?
Dave Tweed

3

Theo bảng dữ liệu tại địa chỉ 0x03 trong bảng 4-1, có một trường 'Ngày'. Ở cuối dòng có một mô tả ngắn:

AddressBit7:3Bit2:0FunctionRange0x03...DayDay1-7

Điều này có nghĩa là ngày có thể được đặt thành bất kỳ số nào trong khoảng từ 1 đến 7. Bạn có thể chọn quy ước của riêng mình vào ngày nào trong tuần. Trên hệ thống POSIX Thứ hai được định nghĩa là 1, tôi nghĩ đó là một tiêu chuẩn tốt. Rồi thứ ba = 2; Thứ tư = 3; ...

Ngày = 0 không được ghi lại, vì vậy đừng sử dụng nó.

Trên Linux, con số này có thể dễ dàng được tìm thấy bằng cách sử dụng lệnh date +%u, mà ngày nay trả lời 6là thứ bảy. Nếu bạn muốn tính toán này cục bộ trên PIC của bạn, bạn sẽ phải tìm ra C-thư viện mà cụ công thức, tôi tin rằng strftimetrong <time.h>không chỉ đó, nhưng tôi không phải là đủ C lập trình để giải thích làm thế nào để sử dụng thư viện nói riêng. Nó là một thư viện thường được sử dụng, vì vậy tài liệu rất dễ tìm.


Thứ Hai cũng là ngày 1 (Chủ nhật ngày 7) theo tiêu chuẩn quốc tế ISO-8601.
Joris Groosman

0

Ngày trong tuần là tùy ý . Bạn xác định nó. Bạn có thể sử dụng Chủ nhật Julian = Ngày 1. Bạn có thể sử dụng Thứ Hai là Ngày 1 vì Chủ nhật là ngày thứ 7. Bạn có thể sử dụng Thứ Sáu là Ngày 1 vì đó là ngày đầu tiên của cuối tuần. Bạn có thể sử dụng Thứ Ba là Ngày 1 vì bạn ghét Thứ Hai.


2
Đây không phải là một câu trả lời. Nó dường như là một cơn thịnh nộ của một số loại, nhưng tôi không thể tìm ra vấn đề là gì. Câu hỏi ban đầu là làm thế nào để có được từ một ngày cụ thể đến đúng ngày trong tuần.
Dave Tweed

@DaveTweed Tôi đang giải thích rằng Ngày trong tuần là tùy ý. Nó không có ý nghĩa cố định đối với RTC. Cho đến khi OP xác định ngày anh ấy tin là ngày 1, thì không thể có được "ngày chính xác trong tuần" như bạn đã nói.
Người qua đường

Nếu bạn tin rằng câu hỏi không đầy đủ, thì điều này đáng lẽ phải được đăng dưới dạng bình luận chứ không phải câu trả lời.
Dave Tweed

Thực tế là nó tùy ý không có nghĩa là không thể tính được, một khi bạn đặt tiêu chuẩn của mình.
Joris Groosman
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.