handling iso datetime in nrf52 - bluetooth-lowenergy

I am using nrf52832 chip. I will be receiving time in isoFormat.
I am wondering how convert the iso format to get the date and time in my C program.
I am not using any RTOS but doing everything on baremetal.

Have asked the same question in nordic devzone:
https://devzone.nordicsemi.com/question/184631/handling-iso-datetime-in-nrf52/
We are going with the solution where we ill pass the isoTime as a string and convert that to time_t using the solution in:
https://cboard.cprogramming.com/c-programming/169114-how-convert-string-time_t.html
const char T[] = "2017-12-26T10:53:58.025905";
int year = 0, month = 0, day = 0, hour = 0, min = 0;
sscanf(T, "%4d-%2d-%2dT%2d:%2d", &year, &month, &day, &hour, &min);

Related

How should I format a date to always respect the specified format? [duplicate]

This question already has answers here:
Go time.Time.UTC() sometimes gives 7 digits, sometimes 9
(1 answer)
prevent json.Marshal time.Time removing trailing zeros
(1 answer)
Closed 2 months ago.
I have a Go API that is supposed to return a timestamp in the following format (Java notation but should be understandable):
yyyy-MM-dd'T'HH:mm:ss.SSSSSS'Z'
My Go API will build this timestamp as follows:
func ParseToTimestamp(duration string, systemTime time.Time) (string, error) {
parsedDuration, err := time.ParseDuration(duration)
if err != nil {
return "", err
}
validity := systemTime.Add(parsedDuration)
return validity.Format("2006-01-02T15:04:05.999999Z"), nil
}
I've noticed, however, that this formatted string is not always respecting the wished format. For example, if I pass a date which has 0 nano-seconds:
duration := "10m"
systemTime := time.Date(1990, time.January, 24, 0, 0, 0, 0, time.UTC) //no nano-seconds
timestamp, _ := fxcash.ParseToTimestamp(duration, systemTime)
fmt.Println(timestamp)
>> 1990-01-24T00:10:00Z
However, if I pass a date which has 120k nano-seconds:
duration := "10m"
systemTime := time.Date(1990, time.January, 24, 0, 0, 0, 120000, time.UTC) //120k nano-seconds
timestamp, _ := fxcash.ParseToTimestamp(duration, systemTime)
fmt.Println(timestamp)
>> 1990-01-24T00:10:00.00012Z
Generally speaking, this causes an issue because the service that consumes my Go output expects to have exactly 6 nano-seconds, even if they were only zeros .000000Z.
Is there a way to do that without heavy parsing/ugly splitting using standard Go Libraries?
Sorry if this question is basic but I'm very new to Go, I've looked for examples on the web but couldn't find any.

Is this the best way of getting tomorrow 09:00? [duplicate]

This question already has an answer here:
How to get specific time from next day
(1 answer)
Closed 2 years ago.
I want to get a datetime object for tomorrow morning 09:00 in Go. My current take is this:
now := time.Now()
tomorrowMorning := time.Date(now.Year(), now.Month(), now.Day(), 9, 0, 0, 0, time.UTC).AddDate(0, 0, 1))
It seems oddly verbose though. Isn't there a simpler way of doing this?
Simplify by adding 1 to the day directly.
now := time.Now()
tomorrowMorning := time.Date(now.Year(), now.Month(), now.Day() + 1, 9, 0, 0, 0, time.UTC)
Run it on the playground.
The time.Date function normalizes the day.

Create a Julia Datetime from a TimePeriod and StartDate

I want to convert an Int64 representing the number of microseconds passed since 12:00:00 midnight, January 1, 0001 (0:00:00 UTC on January 1, 0001, in the Gregorian calendar) into a Julia datetime.
julia> time = Dates.Microsecond(6369175082331949400)
julia> Dates.format(time, "yyyymmdd HH:MM:SS.sss")
If you need a DateTime, just make sure you have your Int64 correctly in milliseconds, and you can use the (undocumented) UTInstant constructor, and then later add back the fractional microseconds (comment: your example number, 6369175082331949400, seems big for recent Gregorian time in microseconds, it may be nanoseconds):
julia> using Dates
julia> t = now().instant
Dates.UTInstant{Millisecond}(63694318624788 milliseconds)
julia> dump(t)
Dates.UTInstant{Millisecond}
periods: Millisecond
value: Int64 63694318624788
julia> t2 = Dates.UTInstant(Millisecond(63691750823319))
Dates.UTInstant{Millisecond}(63691750823319 milliseconds)
julia> DateTime(t2)
2019-04-24T01:00:23.319
julia> t3 = DateTime(t2)+ Dates.Microsecond(494)
2019-04-24T01:00:23.319
You can get what you want using Dates.epochms2datetime and applying an adjustment to it for your case as shown below.
Lets take datetime_value as the date we are interested in getting:
datetime_value = Dates.DateTime(2019,1,1,0,0,0)
date_start = Dates.DateTime(1,1,1,0,0,0)
date_diff = datetime_value - date_start
This gives you a value of 63681897600000 milliseconds for date_diff. Now Dates.epochms2datetime considers start of epoch as 0000-01-01T00:00:00. So we need to add 1 Year and 1 Day to the result after using Dates.epochms2datetime to arrive at our datetime value from the milliseconds value:
julia> Dates.epochms2datetime(63681897600000) + Dates.Year(1) + Dates.Day(1)
2019-01-01T00:00:00
I'm not sure I completely understand the question, as Dates.Microsecond merely returns the Int64 value of a Date or Time. However, you can create the DateTime value from a specific date and then work from there. Subtraction is allowed for DateTime values and it returns the difference in milliseconds.
using Dates
dateThen = DateTime(1, 1, 1, 0, 0, 0)
dateNow = now(UTC)
diff = dateNow - dateThen
dump(diff * 1000)
Int64 63694261047549000 (or whatever time you run it.)
Using some of the ideas provided, I came up with:
function convert_datetime(time)::DateTime
num = div(time, 100000)
remainder = rem(time, 100000)
time = DateTime(Dates.UTInstant(Millisecond(num))) + Dates.Day(1)
# time = Dates.epochms2datetime(trade.date_time/100000) + Dates.Year(1) + Dates.Day(1)
time + Dates.Microsecond(remainder)
end

Go time comparison

I'm trying to create simple function just to change time zone of a time to another (Lets assume UTC to +0700 WIB). Here is the source code. I have 2 functions, first GenerateWIB which will change just your time zone into +0700 WIB with same datetime. Second is GenerateUTC which will change given time's timezone into UTC. GenerateUTC works perfectly while another is not.
expect := time.Date(2016, 12, 12, 1, 2, 3, 4, wib)
t1 := time.Date(2016, 12, 12, 1, 2, 3, 4, time.UTC)
res := GenerateWIB(t1)
if res != expect {
fmt.Printf("WIB Expect %+v, but get %+v", expect, res)
}
The res != expect always fullfilled with this result.
WIB Expect 2016-12-12 01:02:03.000000004 +0700 WIB, but get 2016-12-12 01:02:03.000000004 +0700 WIB
But it is the same time right? Did i miss something?
There is an .Equal() method to compare dates :
if !res.Equal(expect) {
...
Quoting the doc :
Note that the Go == operator compares not just the time instant but also the Location and the monotonic clock reading. Therefore, Time values should not be used as map or database keys without first guaranteeing that the identical Location has been set for all values, which can be achieved through use of the UTC or Local method, and that the monotonic clock reading has been stripped by setting t = t.Round(0). In general, prefer t.Equal(u) to t == u, since t.Equal uses the most accurate comparison available and correctly handles the case when only one of its arguments has a monotonic clock reading.
If you look at the code for the time.Time(*) struct, you can see that this struct has three private fields :
type Time struct {
...
wall uint64
ext int64
...
loc *Location
}
and the comments about those fields clearly indicate that, depending on how the Time struct was built, two Time describing the same point in time may have different values for these fields.
Running res == expect compares the values of these inner fields,
running res.Equal(expect) tries to do the thing you expect.
(*) time/time.go source code on master branch as of oct 27th, 2020
Dates in golang must be compared with Equal method. Method Date returns Time type.
func Date(year int, month Month, day, hour, min, sec, nsec int, loc *Location) Time
and Time type have Equal method.
func (t Time) Equal(u Time) bool
Equal reports whether t and u represent the same time instant. Two times can be equal even if they are in different locations. For example, 6:00 +0200 CEST and 4:00 UTC are Equal. See the documentation on the Time type for the pitfalls of using == with Time values; most code should use Equal instead.
Example
package main
import (
"fmt"
"time"
)
func main() {
secondsEastOfUTC := int((8 * time.Hour).Seconds())
beijing := time.FixedZone("Beijing Time", secondsEastOfUTC)
// Unlike the equal operator, Equal is aware that d1 and d2 are the
// same instant but in different time zones.
d1 := time.Date(2000, 2, 1, 12, 30, 0, 0, time.UTC)
d2 := time.Date(2000, 2, 1, 20, 30, 0, 0, beijing)
datesEqualUsingEqualOperator := d1 == d2
datesEqualUsingFunction := d1.Equal(d2)
fmt.Printf("datesEqualUsingEqualOperator = %v\n", datesEqualUsingEqualOperator)
fmt.Printf("datesEqualUsingFunction = %v\n", datesEqualUsingFunction)
}
datesEqualUsingEqualOperator = false
datesEqualUsingFunction = true
resources
Time type documentation
Equal method documentation
time.Date

Parsing an 8 bit char array to integer

I am new to Arduino and all I want to do is parse a String of binary numbers to an exact integer representation.
char* byte1 = "11111111"
int binary1 = atoi(byte1);
Serial.print(binary1);
However this prints out: -19961
Can anyone explain why? I am coming from a Java and JavaScript perspective.
atoi converts a decimal (base 10) string to int. If you want to convert a binary string to int, you can use strtol:
char *byte1 = "11111111";
int val1 = strtol(byte1, 0, 2);
std::cout << val1 << std::endl;
strtol can convert any base -- the 3rd argument is the base to use.
You get -19961 because on Arduino int is 16 bit wide and cannot hold any number bigger than 32767. To hold an integer representation of 11111111 you have to use long (which on Arduino is 32 bit) and strtol.
long val = strtol(byte1, NULL, 10);

Resources