Webserver+3d print

Dependents:   Nucleo

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers date_time.c Source File

date_time.c

Go to the documentation of this file.
00001 /**
00002  * @file date_time.c
00003  * @brief Date and time management
00004  *
00005  * @section License
00006  *
00007  * Copyright (C) 2010-2017 Oryx Embedded SARL. All rights reserved.
00008  *
00009  * This program is free software; you can redistribute it and/or
00010  * modify it under the terms of the GNU General Public License
00011  * as published by the Free Software Foundation; either version 2
00012  * of the License, or (at your option) any later version.
00013  *
00014  * This program is distributed in the hope that it will be useful,
00015  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00016  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00017  * GNU General Public License for more details.
00018  *
00019  * You should have received a copy of the GNU General Public License
00020  * along with this program; if not, write to the Free Software Foundation,
00021  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
00022  *
00023  * @author Oryx Embedded SARL (www.oryx-embedded.com)
00024  * @version 1.7.6
00025  **/
00026 
00027 //Dependencies
00028 #include <stdio.h>
00029 #include <string.h>
00030 #include "date_time.h"
00031 
00032 #if defined(_WIN32)
00033    #include <time.h>
00034 #endif
00035 
00036 //Days
00037 static const char days[8][10] =
00038 {
00039    "",
00040    "Monday",
00041    "Tuesday",
00042    "Wednesday",
00043    "Thursday",
00044    "Friday",
00045    "Saturday",
00046    "Sunday"
00047 };
00048 
00049 //Months
00050 static const char months[13][10] =
00051 {
00052    "",
00053    "January",
00054    "February",
00055    "March",
00056    "April",
00057    "May",
00058    "June",
00059    "July",
00060    "August",
00061    "September",
00062    "October",
00063    "November",
00064    "December"
00065 };
00066 
00067 
00068 /**
00069  * @brief Format system time
00070  * @param[in] time System time
00071  * @param[out] str NULL-terminated string representing the specified time
00072  * @return Pointer to the formatted string
00073  **/
00074 
00075 const char_t *formatSystemTime(systime_t time, char_t *str)
00076 {
00077    uint16_t hours;
00078    uint8_t minutes;
00079    uint8_t seconds;
00080    uint16_t milliseconds;
00081    static char_t buffer[24];
00082 
00083    //Retrieve milliseconds
00084    milliseconds = time % 1000;
00085    time /= 1000;
00086    //Retrieve seconds
00087    seconds = time % 60;
00088    time /= 60;
00089    //Retrieve minutes
00090    minutes = time % 60;
00091    time /= 60;
00092    //Retrieve hours
00093    hours = time;
00094 
00095    //The str parameter is optional
00096    if(!str) str = buffer;
00097 
00098    //Format system time
00099    if(hours > 0)
00100    {
00101       sprintf(str, "%" PRIu16 "h %02" PRIu8 "min %02" PRIu8 "s %03" PRIu16 "ms",
00102          hours, minutes, seconds, milliseconds);
00103    }
00104    else if(minutes > 0)
00105    {
00106       sprintf(str, "%" PRIu8 "min %02" PRIu8 "s %03" PRIu16 "ms",
00107          minutes, seconds, milliseconds);
00108    }
00109    else if(seconds > 0)
00110    {
00111       sprintf(str, "%" PRIu8 "s %03" PRIu16 "ms", seconds, milliseconds);
00112    }
00113    else
00114    {
00115       sprintf(str, "%" PRIu16 "ms", milliseconds);
00116    }
00117 
00118    //Return a pointer to the formatted string
00119    return str;
00120 }
00121 
00122 
00123 /**
00124  * @brief Format date
00125  * @param[in] date Pointer to a structure representing the date
00126  * @param[out] str NULL-terminated string representing the specified date
00127  * @return Pointer to the formatted string
00128  **/
00129 
00130 const char_t *formatDate(const DateTime *date, char_t *str)
00131 {
00132    static char_t buffer[40];
00133 
00134    //The str parameter is optional
00135    if(!str) str = buffer;
00136 
00137    //Format date
00138    if(date->dayOfWeek)
00139    {
00140       sprintf(str, "%s, %s %" PRIu8 ", %" PRIu16 " %02" PRIu8 ":%02" PRIu8 ":%02" PRIu8,
00141          days[MIN(date->dayOfWeek, 7)], months[MIN(date->month, 12)], date->day,
00142          date->year, date->hours, date->minutes, date->seconds);
00143    }
00144    else
00145    {
00146       sprintf(str, "%s %" PRIu8 ", %" PRIu16 " %02" PRIu8 ":%02" PRIu8 ":%02" PRIu8,
00147          months[MIN(date->month, 12)], date->day, date->year,
00148          date->hours, date->minutes, date->seconds);
00149    }
00150 
00151    //Return a pointer to the formatted string
00152    return str;
00153 }
00154 
00155 
00156 /**
00157  * @brief Get current date and time
00158  * @param[out] date Pointer to a structure representing the date and time
00159  **/
00160 
00161 void getCurrentDate(DateTime *date)
00162 {
00163    //Retrieve current time
00164    time_t time = getCurrentUnixTime();
00165 
00166    //Convert Unix timestamp to date
00167    convertUnixTimeToDate(time, date);
00168 }
00169 
00170 
00171 /**
00172  * @brief Get current time
00173  * @return Unix timestamp
00174  **/
00175 
00176 time_t getCurrentUnixTime(void)
00177 {
00178 #if defined(_WIN32)
00179    //Retrieve current time
00180    return time(NULL);
00181 #else
00182    //Not implemented
00183    return 0;
00184 #endif
00185 }
00186 
00187 
00188 /**
00189  * @brief Convert Unix timestamp to date
00190  * @param[in] t Unix timestamp
00191  * @param[out] date Pointer to a structure representing the date and time
00192  **/
00193 
00194 void convertUnixTimeToDate(time_t t, DateTime *date)
00195 {
00196    uint32_t a;
00197    uint32_t b;
00198    uint32_t c;
00199    uint32_t d;
00200    uint32_t e;
00201    uint32_t f;
00202 
00203    //Negative Unix time values are not supported
00204    if(t < 1) t = 0;
00205 
00206    //Clear milliseconds
00207    date->milliseconds = 0;
00208 
00209    //Retrieve hours, minutes and seconds
00210    date->seconds = t % 60;
00211    t /= 60;
00212    date->minutes = t % 60;
00213    t /= 60;
00214    date->hours = t % 24;
00215    t /= 24;
00216 
00217    //Convert Unix time to date
00218    a = (uint32_t) ((4 * t + 102032) / 146097 + 15);
00219    b = (uint32_t) (t + 2442113 + a - (a / 4));
00220    c = (20 * b - 2442) / 7305;
00221    d = b - 365 * c - (c / 4);
00222    e = d * 1000 / 30601;
00223    f = d - e * 30 - e * 601 / 1000;
00224 
00225    //January and February are counted as months 13 and 14 of the previous year
00226    if(e <= 13)
00227    {
00228       c -= 4716;
00229       e -= 1;
00230    }
00231    else
00232    {
00233       c -= 4715;
00234       e -= 13;
00235    }
00236 
00237    //Retrieve year, month and day
00238    date->year = c;
00239    date->month = e;
00240    date->day = f;
00241 
00242    //Calculate day of week
00243    date->dayOfWeek = computeDayOfWeek(c, e, f);
00244 }
00245 
00246 
00247 /**
00248  * @brief Convert date to Unix timestamp
00249  * @param[in] date Pointer to a structure representing the date and time
00250  * @return Unix timestamp
00251  **/
00252 
00253 time_t convertDateToUnixTime(const DateTime *date)
00254 {
00255    uint_t y;
00256    uint_t m;
00257    uint_t d;
00258    uint32_t t;
00259 
00260    //Year
00261    y = date->year;
00262    //Month of year
00263    m = date->month;
00264    //Day of month
00265    d = date->day;
00266 
00267    //January and February are counted as months 13 and 14 of the previous year
00268    if(m <= 2)
00269    {
00270       m += 12;
00271       y -= 1;
00272    }
00273 
00274    //Convert years to days
00275    t = (365 * y) + (y / 4) - (y / 100) + (y / 400);
00276    //Convert months to days
00277    t += (30 * m) + (3 * (m + 1) / 5) + d;
00278    //Unix time starts on January 1st, 1970
00279    t -= 719561;
00280    //Convert days to seconds
00281    t *= 86400;
00282    //Add hours, minutes and seconds
00283    t += (3600 * date->hours) + (60 * date->minutes) + date->seconds;
00284 
00285    //Return Unix time
00286    return t;
00287 }
00288 
00289 
00290 /**
00291  * @brief Calculate day of week
00292  * @param[in] y Year
00293  * @param[in] m Month of year (in range 1 to 12)
00294  * @param[in] d Day of month (in range 1 to 31)
00295  * @return Day of week (in range 1 to 7)
00296  **/
00297 
00298 uint8_t computeDayOfWeek(uint16_t y, uint8_t m, uint8_t d)
00299 {
00300    uint_t h;
00301    uint_t j;
00302    uint_t k;
00303 
00304    //January and February are counted as months 13 and 14 of the previous year
00305    if(m <= 2)
00306    {
00307       m += 12;
00308       y -= 1;
00309    }
00310 
00311    //J is the century
00312    j = y / 100;
00313    //K the year of the century
00314    k = y % 100;
00315 
00316    //Compute H using Zeller's congruence
00317    h = d + (26 * (m + 1) / 10) + k + (k / 4) + (5 * j) + (j / 4);
00318 
00319    //Return the day of the week
00320    return ((h + 5) % 7) + 1;
00321 }
00322