Is there a utility or library that could shift a UTC date/time string like "24/11/10,16:55:41" to a time zone? Like -6, +2, etc.. I'm using the time from a GSM module, derived as "24/11/10,16:55:41-20". The -20 being the UTC offset in 1/4 hours, based on my physical location.
How it's best done depends on which Arduino Board / Processor you're using. And, if you're using any existing time libraries. You haven't told us any of those things. Also, where is this string coming from in the first place?
I use the Arduino Time library (TimeLib.h), and add or subtract the appropriate number of seconds from the unix time.
Example:
//time library demo
#include "TimeLib.h"
tmElements_t te; //Time elements structure
time_t unixTime; // a time stamp
void setup() {
Serial.begin(9600);
// set internal clock time and date. Alternatives
// setTime(hr,min,sec,day,mnth,yr);
te.Second = 0;
te.Hour = 23; //11 pm
te.Minute = 0;
te.Day = 6;
te.Month = 11;
te.Year = 2020 - 1970;
unixTime = makeTime(te); //Y2K, in seconds = 946684800UL
Serial.print("unixTime = ");
Serial.println(unixTime);
setTime(unixTime); //set the current time to the above entered
Serial.print("now() = ");
Serial.println(now());
// print as date_time
print_date_time();
// add
unixTime += 3600UL; //adjust for DST in spring
setTime(unixTime);
Serial.println("After adding DST offset");
Serial.print("now() = ");
Serial.println(now());
print_date_time();
}
void print_date_time() { //easy way to print date and time
char buf[40];
sprintf(buf, "%02d/%02d/%4d %02d:%02d:%02d", day(), month(), year(), hour(), minute(), second());
Serial.println(buf);
}
void loop() {
static int minutes_past_midnight, last_print_time = 0;
// check the clock
minutes_past_midnight = hour() * 60 + minute();
// every 5 minutes, print the data and time
if (minutes_past_midnight != last_print_time && minutes_past_midnight % 5 == 0) {
last_print_time = minutes_past_midnight;
print_date_time();
}
}
Which is fine except if you're working with an ESP32. Then, better techniques exist.
I'm using a Nano, with no time library, so far.
Since I'm getting the time string from the GSM, I can use and display the date/time elements.
It's just Timezone+/- hours off.
Per my post, the time string is coming from a GSM module.
Then @jremington's approach is a good way to go.
Thanks much Jremington,
Looks like I can use the DST adjustment method for the Time Zone offset I receive from the carrier.
Maybe useful
#include "TimeLib.h"
tmElements_t te; //Time elements structure
time_t unixTime; // a time stamp
int yy, mo, dd, hh, mi, ss, tZone;
char inData[] = "24/11/10,16:55:41-20";
void setup()
{
Serial.begin(115200);
sscanf(inData, "%2d%*c%2d%*c%2d%*c%2d%*c%2d%*c%2d%3d", &yy, &mo, &dd, &hh, &mi, &ss, &tZone);
te.Second = ss;
te.Hour = hh;
te.Minute = mi;
te.Day = dd;
te.Month = mo;
te.Year = (yy + 2000) - 1970;
unixTime = makeTime(te);
Serial.print("unixTime = ");
Serial.println(unixTime);
Serial.println((tZone * 15) / 60);
setTime(unixTime + (tZone * 15 * 60));
char buf[40];
sprintf(buf, "%02d/%02d/%4d %02d:%02d:%02d", day(), month(), year(), hour(), minute(), second());
Serial.println(buf);
}
void loop()
{
}
Careful with this. (tZone * 15 * 60)
will overflow the range of int
(which is only 16 bits wide on the Nano) if the time zone is more than ±9 hours from UTC (e.g., China, Australia, Hawaii, and many more). Use something like (tZone * 15 * 60UL)
instead.
Thank you
This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.