Jotrin Electronics
Cart
arrow
Description Quantity Total (USD) Operation
loading
Shopping cart products
Shopping cart products : 0
Home > Technology List > Microcontroller UTC time zone conversion

Microcontroller UTC time zone conversion

Update Time: 2019-12-20 12:11:28

I. creation background

Previously, I made a project about STM32 low-power signal acquisition, using STM32L031 single-chip microcomputer. The project requirements are as follows:

The device is battery-powered, detects a signal from the sensor and sends it out wirelessly.Each time the signal collected by the device is transmitted, it takes tens of mS, and other times it goes into deep sleep to save power.

The main point of this project is that the working time of the equipment is uncertain every day. The customer may request to collect it once an hour, once a day or only on working days.


Because the working interval is uncertain and the UTC time is easily available over the wireless network.Therefore, I decided to make a calendar, using the MCU RTC peripheral and alarm clock function, each time after the completion of equipment collection, before entering hibernation, according to the working mechanism set by the customer, the next RTC alarm clock will be set, through the RTC alarm clock interrupt event to wake up the program.

Ii. UTC investigation

UTC has been investigated for a BUG in Y2038, which was officially released on Tuesday, January 19, 2038 03:14:07 am(GMT).Because the 32-bit computer system with a signed 32-bit integer to store a time_t value, that is to say t_TIme only by the number 31 binary (first used to represent the positive and negative), and its maximum value is converted to a decimal 2147483647, converted to a date and time is just on January 19, 2038 03:14:07 am (GMT), and that one second later, t_TIme value will be - 2147483647 32-bit software and hardware system of crazy time display the date.

Now is not too far from 2038, so this hidden danger can not be buried here (must enter this time to write the code I want to use next time, can not next time in research).

Iii. Scheme design

Since the STM32 RTC is definitely 32-bit, there are two methods in front of me:

Method 1: in the general rule, UTC=0 means 1970/1/1-0 :0:0. I shift the time in the project to, say, 2010/1/1-0 :0:0, so that Y2038 becomes 2078.

Method 2: in C language time. h file, int is used to count seconds.I use uint to count the seconds, so that the BUG of y2k can be postponed to Beijing time 2106/2/7 14:28:15

So, in the end, I chose plan two without hesitation, because I didn't have to change the standard that everyone follows.

Iv. Programming

Define the program structure type

Typedef struct {uint8_t tm_sec;Uint8_t tm_min;Uint8_t tm_hour;Uint8_t tm_mday;Uint8_t tm_mon;Uint8_t tm_wday;Uint16_t tm_year;/ / uint16_t tm_yday;} TImeType;

Create a variable

Static const uint16_t NonleapYearMonth[12] = {31,//131 + 28, //231 + 28 + 31,// 331 + 28 + 31,// 431 + 28 + 30, //531 + 28 + 30 + 30,//631 + 28 + 30 + 31 + 30 + 31, //731 + 28 + 31 + 30 + 30 + 31, //831 + 28 + 31 + 30 + 30 + 31,//1031 + 28 + 31 + 30 + 31 + 30 + 31 + 31 + 30 + 31 + 30 + 31 + 30 + 30, //1131 + 28 + 31 + 30 + 30 + 30 + 30, //12};Static const uint16_t LeapYearMonth[12] = {31,//131 + 29, //231 + 29 + 31,// 331 + 29 + 31,// 431 + 29 + 30, //531 + 29 + 30 + 31,//631 + 29 + 30 + 30 + 30 + 31, //731 + 29 + 30 + 30 + 30 + 31, //831 + 29 + 30 + 30 + 30 + 31,//1031 + 29 + 30 + 30 + 30 + 31 + 31 + 30 + 31 + 30 + 31 + 30 + 30, //1131 + 29 + 31 + 30 + 30 + 30 + 30, //12};

Uint8_t alg_IsLeapYear(uint32_t year){if((year % 4 == 0) && ((year % 100!= 0) || (year % 400 == 0))) // is divisible by 4, not by 100, but by 400.{return 1;Else {return 0;TimeType alg_Utc2LocalTime(uint32_t UtcVal, int8_t TimeZone){uint32_t I = 0;TimeType LocalTime;Uint32_t Hour, Days, Year;LocalTime. Tm_sec = UtcVal % 60;// localtime.tm_min =(UtcVal/60)%60;Hour=(UtcVal/60)/60;Localtime.tm_hour =Hour%24+TimeZone;If (localtime.tm_hour >23){localtime.tm_hour -=24;Days = 24 + 1 Hour /;} else {Days = Hour / 24;} LocalTime. Tm_wday = (Days + 4) % 7;// calculate the week, 0-means Sunday note: 1970-1-1 is the week // note: 400 years = 146,097 days,100 years = 36,524 days,4 years =1461 days Year = 1970;Year += (Days/146097)*400;Days % = 146097;Year += (Days/36525)*100;Days % = 36525;Year + = (Days / 1461) * 4;Days % = 1461;If (alg_IsLeapYear(Year)){Days--; if(alg_IsLeapYear(Year)){Days--;} Days - = 365;Year++;} the if (!Alg_IsLeapYear (Year) && (Days == 365)){Year++;LocalTime. Tm_mday = 1;LocalTime. Tm_mon = 1;LocalTime. Tm_year = Year;Return a LocalTime;} LocalTime. Tm_year = Year;The LocalTime. Tm_mon = 0;The LocalTime. Tm_mday = 0;If (alg_IsLeapYear(Year))// this Year is a leap Year {for (I = 0;I < 12;I ++){if (Days < LeapYearMonth[I]){localtime.tm_mon = I + 1;If (I == 0){localtime.tm_mday = Days;}else{localtime.tm_mday = days-leapyearmonth [i-1];} LocalTime. Tm_mday + +;Return a LocalTime;Else // this year is a normal year {for (I = 0;I < 12;I ++){if (Days < NonleapYearMonth[I]){localtime.tm_mon = I + 1;If (I == 0){localtime.tm_mday = Days;}else{localtime.tm_mday = days-nonleapyearmonth [i-1];} LocalTime. Tm_mday + +;Return a LocalTime;}}} return LocalTime;}uint32_t alg_LocalTime2Utc(TimeType LocalTime, int8_t TimeZone){uint32_t y = localtime.tm_year-1970;// see how many 400 years, how many 100 years, how many 4 years uint32_t dy = (y / 400);Uint32_t days = dy * (400 * 365 + 97);// the number of days in 400 years dy = (y % 400) / 100;Days += dy * (100 * 365 + 25);// days in 100 years dy = (y % 100) / 4;Days += dy * (4 * 365 + 1);// the number of days in 4 years dy = y % 4;// note: here 1972 is a leap year, only 2 years from 1970.If (dy == 3)// in this 4 years, there is no leap year is less than 1 day {day ++;If (localtime.tm_mon!) {if (localtime.tm_mon!) {if (localtime.tm_mon!) {if (localtime.tm_mon!= 1){if(alg_IsLeapYear(localtime.tm_year))// see if this year is a leap year or a flat year {days += LeapYearMonth[(localtime.tm_mon-1) -1];} else {days += NonleapYearMonth[(localtime.tm_mon-1) -1];// if the number of months given is x, only x-1 integer months}}days += localtime.tm_mday-1;Return (days * 24 * 3600 + ((uint32_t) localtime.tm_hour-timezone)* 3600 + (uint32_t) localtime.tm_min * 60 + (uint32_t) localtime.tm_sec);} above, the basic program API is complete.

When called, only the following two functions can be used for mutual rotation:

TimeType alg_Utc2LocalTime(uint32_t UtcVal, int8_t TimeZone);Uint32_t alg_LocalTime2Utc(TimeType LocalTime, int8_t TimeZone);

Tag: UTC

Share:

Previous: Lite-On Technology Selected as a Member of 2012 DJSI two years in a row, ranked as the Sector Leader of Electronic Component &amp; Equipment

Next: Ams a number of innovative sensor technologies appear in MWC

 

Cart

Account Center

jotrin03

Live Chat

sales@jotrin.com