timec.c 3.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122
  1. #include "main.h"
  2. __flash const unsigned char mi[] = {3, 3, 6, 1, 4, 6, 2, 5, 0, 3, 5};
  3. unsigned char calc_weekday(struct tm *ct) {
  4. unsigned char w, x;
  5. x = ct->tm_year - 100;
  6. w = x%7;
  7. if(x != 0) { /* if year is not 2000 */
  8. /* Count only past years, for example if current year is 2004, count only 2000-2003, so x-- */
  9. x--;
  10. w += x >> 2; /* add number of years which are divisible by 4 4 */
  11. w -= x/100; /* subtract number of years which are divisible by 100 */
  12. w++; /* add the year 2000 which is divisible by 400 */
  13. }
  14. /* Add first weekday (Saturday 2000-01-01) */
  15. w+=4;
  16. /* Months */
  17. if(ct->tm_mon+1 > 1) { /* if it's not January */
  18. w += mi[ct->tm_mon+1 - 2]; /* add array increment */
  19. }
  20. /* Days */
  21. w += ct->tm_mday;
  22. /*
  23. ** If current month is March or later, and it's a leap year, this means February
  24. ** was 29 days so we have to add 1.
  25. */
  26. if(ct->tm_mon+1 > 2)
  27. if(!(ct->tm_year&3)) w+=1;
  28. /* Result modulo 7 */
  29. return (w%7)+1; /* 1 = Monday, 7 = Sunday */
  30. }
  31. signed int local_time_diff(time_t time) {
  32. signed char offset = TIME_OFFSET;
  33. unsigned char t;
  34. struct tm *ct = gmtime(&time);
  35. unsigned char weekday = calc_weekday(ct);
  36. if (ct->tm_mon+1 == 3 || ct->tm_mon+1 == 10){
  37. t = 35 + weekday - ct->tm_mday;
  38. t += 31;
  39. t = t%7;
  40. t = 31-t;
  41. if (ct->tm_mon+1 == 3){ // March
  42. if (ct->tm_mday==t) { // last Sunday
  43. if (ct->tm_hour >= 2 )
  44. offset = SUMMER_TIME_OFFSET;
  45. } else if (ct->tm_mday > t) { // after last Sunday
  46. offset = SUMMER_TIME_OFFSET;
  47. }
  48. } else { // October
  49. if (ct->tm_mday == t) { // last Sunday
  50. if(ct->tm_hour < 2)
  51. offset = SUMMER_TIME_OFFSET;
  52. } else if (ct->tm_mday < t) { // before last Sunday
  53. offset = SUMMER_TIME_OFFSET;
  54. }
  55. }
  56. } else if (ct->tm_mon+1 > 3 && ct->tm_mon+1 < 10) {
  57. offset = SUMMER_TIME_OFFSET;
  58. }
  59. return offset;
  60. }
  61. const char *local_time_mark(time_t time) {
  62. static char buf[4];
  63. signed int time_diff = local_time_diff(time);
  64. if (time_diff < 0) {
  65. buf[0] = '-';
  66. time_diff = -time_diff;
  67. } else {
  68. buf[0] = '+';
  69. }
  70. buf[1] = time_diff/10 + '0'; /* never greater than 23 */
  71. buf[2] = time_diff%10 + '0';
  72. buf[3] = '\0';
  73. return buf;
  74. }
  75. /* Make ISO time string */
  76. char *get_iso_time(time_t time, unsigned char local) {
  77. static char output[32];
  78. if (local)
  79. time += local_time_diff(time) * (signed int)3600;
  80. struct tm *ct = gmtime(&time);
  81. xsprintf(output, PSTR("%4u-%02u-%02uT%02u:%02u:%02u.000%s"), ct->tm_year+1900, ct->tm_mon+1, ct->tm_mday, ct->tm_hour, ct->tm_min, ct->tm_sec, local?local_time_mark(time):"Z");
  82. return output;
  83. }
  84. /*---------------------------------------------------------*/
  85. /* User Provided Timer Function for FatFs module */
  86. /*---------------------------------------------------------*/
  87. DWORD get_fattime (void)
  88. {
  89. struct tm *stm;
  90. time_t localtime = utc + local_time_diff(utc) * (signed int)3600;
  91. stm = gmtime(&localtime);
  92. return (DWORD)(stm->tm_year - 80) << 25 |
  93. (DWORD)(stm->tm_mon + 1) << 21 |
  94. (DWORD)stm->tm_mday << 16 |
  95. (DWORD)stm->tm_hour << 11 |
  96. (DWORD)stm->tm_min << 5 |
  97. (DWORD)stm->tm_sec >> 1;
  98. }
  99. void iso_time_to_filename(char *time) {
  100. while (*time) {
  101. switch (*time) {
  102. case ':': *time = '-'; break;
  103. case '+': *time = 'p'; break;
  104. }
  105. time++;
  106. }
  107. }