Watch, Follow, &
Connect with Us

For forums, blogs and more please visit our
Developer Tools Community.


Welcome, Guest
Guest Settings
Help

Thread: UTC Time


This question is answered.


Permlink Replies: 11 - Last Post: Feb 16, 2018 7:49 PM Last Post By: Ted Lyngmo Threads: [ Previous | Next ]
Garrett B

Posts: 77
Registered: 10/2/16
UTC Time  
Click to report abuse...   Click to reply to this thread Reply
  Posted: Feb 1, 2018 6:49 PM
Hi

I have a 4-byte UTC value, representing the number of seconds since 1970.

Is here a library function to convert this to SYSTEMTIME, or some other Embarcadero time/date data type?

Essentially I want to display the UTC value in a human-readable form.

Thanks

Garrett
Ted Lyngmo

Posts: 117
Registered: 10/3/06
Re: UTC Time  
Click to report abuse...   Click to reply to this thread Reply
  Posted: Feb 2, 2018 3:53 AM   in response to: Garrett B in response to: Garrett B
Garrett B wrote:

I have a 4-byte UTC value, representing the number of seconds since 1970.

Is it a time_t value that you got from using time() in the same program or were those 4 bytes handed to you from some external source?

Is here a library function to convert this to SYSTEMTIME, or some other Embarcadero time/date data type?

Essentially I want to display the UTC value in a human-readable form.

If it's really a time_t value:
#include <time.h>
 
const char* time_t_to_asciitime(const time_t& time_since_epoch, bool want_local_time=true) {
    struct tm* timeinfo;
 
    if( want_local_time ) {
          timeinfo = localtime(&time_since_epoch); // Convert time_t to tm as local time
    } else {
          timeinfo = gmtime(&time_since_epoch);    // Convert time_t to tm as UTC time
    }
    return asctime(timeinfo);                      // Convert tm structure to char* string
    // see strftime for more flexibility than asctime offers:
    // http://www.cplusplus.com/reference/ctime/strftime/
}


Br,
Ted
Goran Ekstrom

Posts: 149
Registered: 1/10/04
Re: UTC Time  
Click to report abuse...   Click to reply to this thread Reply
  Posted: Feb 2, 2018 7:15 AM   in response to: Garrett B in response to: Garrett B
Garrett B wrote:
I have a 4-byte UTC value, representing the number of seconds since 1970.
Apparently called "epoch":

https://www.epochconverter.com/

For Delphi:

Epoch := DateTimetoUnix(Now);

There should be a CPB equivalent.
Garrett B

Posts: 77
Registered: 10/2/16
Re: UTC Time  
Click to report abuse...   Click to reply to this thread Reply
  Posted: Feb 2, 2018 7:52 AM   in response to: Goran Ekstrom in response to: Goran Ekstrom
Hi

It is not a time_t value.
It is simply a 32-bit unsigned integer, received from an external library function - I am reading logged events stored by another application.
My question is: do I have to write my own routine for calculating time/date, or is there a library function somewhere for this?
I would have thought this would be quite a common requirement.

  uint32 logTime;   ///< RTC date, seconds since 1970-01-01T00:00:00+00:00 (UTC)


Thanks

Garrett
Ted Lyngmo

Posts: 117
Registered: 10/3/06
Re: UTC Time
Correct
Click to report abuse...   Click to reply to this thread Reply
  Posted: Feb 2, 2018 8:03 AM   in response to: Garrett B in response to: Garrett B
Garrett B wrote:
Hi

It is not a time_t value.
It is simply a 32-bit unsigned integer, received from an external library function - I am reading logged events stored by another application.

That's ok as long as you've got the four bytes in the correct order.

My question is: do I have to write my own routine for calculating time/date, or is there a library function somewhere for this?
I would have thought this would be quite a common requirement.

  uint32 logTime;   ///< RTC date, seconds since 1970-01-01T00:00:00+00:00 (UTC)

Then you should be fine with:
System::TDateTime __fastcall UnixToDateTime(const __int64 AValue, bool AReturnUTC = true);

But, the formatting string of TDateTime is very limited compared to that of the standard http://www.cplusplus.com/reference/ctime/strftime/ so I personally prefer that one.

Br,
Ted
Garrett B

Posts: 77
Registered: 10/2/16
Re: UTC Time  
Click to report abuse...   Click to reply to this thread Reply
  Posted: Feb 2, 2018 8:39 AM   in response to: Ted Lyngmo in response to: Ted Lyngmo
Thanks Ted

That works

Garrett
Remy Lebeau (Te...


Posts: 9,447
Registered: 12/23/01
Re: UTC Time  
Click to report abuse...   Click to reply to this thread Reply
  Posted: Feb 2, 2018 9:47 AM   in response to: Ted Lyngmo in response to: Ted Lyngmo
Ted Lyngmo wrote:

But, the formatting string of TDateTime is very limited compared to
that of the standard

TDateTime::FormatString() is quite flexible, and can produce most of
the same formats that strftime() can. It just doesn't have as many
pre-defined format specifiers as strftime(), that's all.

--
Remy Lebeau (TeamB)
Ted Lyngmo

Posts: 117
Registered: 10/3/06
Re: UTC Time  
Click to report abuse...   Click to reply to this thread Reply
  Posted: Feb 2, 2018 11:58 AM   in response to: Remy Lebeau (Te... in response to: Remy Lebeau (Te...
Remy Lebeau (TeamB) wrote:
Ted Lyngmo wrote:

But, the formatting string of TDateTime is very limited compared to
that of the standard

TDateTime::FormatString() is quite flexible, and can produce most of
the same formats that strftime() can. It just doesn't have as many
pre-defined format specifiers as strftime(), that's all.

TDateTime::FormatString() is really bad when it comes to displaying week numbers. Even strftime had lacking ISO8601 support for week numbers until C99/C++11 so one had to do that as a separate step. Timezone info is also often important. I don't think it is even possible to create an ISO8601 timestamp with FormatString() but perhaps that's fixed now. TDateTime is a nice wrapper, but I think it'd really benefit from a having a strftime method added to it.

Br,
Ted
Remy Lebeau (Te...


Posts: 9,447
Registered: 12/23/01
Re: UTC Time  
Click to report abuse...   Click to reply to this thread Reply
  Posted: Feb 2, 2018 12:24 PM   in response to: Ted Lyngmo in response to: Ted Lyngmo
Ted Lyngmo wrote:

I don't think it is even possible to create an ISO8601 timestamp with
FormatString()

To an extent, it is, if you don't include week dates or time zones (but
you can add a timezone manually after formatting, if needed):

String s = Now().FormatString(L"yyyy'-'mm'-'dd'T'hh':'nn':'ss'.'zzz");


The RTL has DayOfTheWeek() and WeekOf(TheYear)() functions in the
DateUtils unit, which conform to the ISO 8601 definitions of week and
day numbers:

http://docwiki.embarcadero.com/Libraries/en/System.DateUtils.DayOfTheWeek

http://docwiki.embarcadero.com/Libraries/en/System.DateUtils.WeekOfTheYear

TDateTime dtNow = Now();
String s = String().sprintf(L"%04hu-W%02hu-%hu", YearOf(dtNow),
WeekOfTheYear(dtNow), DayOfTheWeek(dtNow));


There is also a DecodeDateWeek() function:

http://docwiki.embarcadero.com/Libraries/en/System.DateUtils.DecodeDateWeek

TDateTime dtNow = Now();
Word Year, Week, Day;
DecodeDateWeek(dtnow, Year, Week, Day);
String s = String().sprintf(L"%04hu-W%02hu-%hu", Year, Week, Day);


And even a DateTimeToISO8601() function:

http://docwiki.embarcadero.com/Libraries/en/System.DateUtils.DateToISO8601

String s = DateTimeToISO8601(Now());


--
Remy Lebeau (TeamB)
Ted Lyngmo

Posts: 117
Registered: 10/3/06
Re: UTC Time  
Click to report abuse...   Click to reply to this thread Reply
  Posted: Feb 2, 2018 7:18 PM   in response to: Remy Lebeau (Te... in response to: Remy Lebeau (Te...
Remy Lebeau (TeamB) wrote:
Ted Lyngmo wrote:

I don't think it is even possible to create an ISO8601 timestamp with
FormatString()

To an extent, it is, if you don't include week dates or time zones (but
you can add a timezone manually after formatting, if needed):

That breaks my interest for FormatString(). Weeks are very important where I live. Digging for answers when there's a standard with ready support isn't necessary. The standard(ish) function and the flexibility to what TDateTime has to offer makes it my choice. What TDateTime could do to offer superiority is a strftime() function with a means of telling its user [anything from mere copy constructor to a programmer] how much memory it needs to allocate - just be C++ about it. The strftime standard is pretty clear nowadays: "This function acts like an a** if you don't supply a buffer large enough". Brilliant... Where the Win32 API has succeeded for ~20-30 years by just supplying no memory to a function to ask what it needs, that part became a mystery for people deciding strftime's response. In order to calculate the exact malloc, you'll have to perform the strftime calculations yourself. If in an embedded environment ... 1 byte? ... 2?

Nice collection of date/time stuff:
String s = Now().FormatString(L"yyyy'-'mm'-'dd'T'hh':'nn':'ss'.'zzz");
// http://docwiki.embarcadero.com/Libraries/en/System.DateUtils.DayOfTheWeek
// http://docwiki.embarcadero.com/Libraries/en/System.DateUtils.WeekOfTheYear
TDateTime dtNow = Now();
String s = String().sprintf(L"%04hu-W%02hu-%hu", YearOf(dtNow),
WeekOfTheYear(dtNow), DayOfTheWeek(dtNow));
// There is also a DecodeDateWeek() function:
// http://docwiki.embarcadero.com/Libraries/en/System.DateUtils.DecodeDateWeek
TDateTime dtNow = Now();
// Word Year, Week, Day;
DecodeDateWeek(dtnow, Year, Week, Day);
String s = String().sprintf(L"%04hu-W%02hu-%hu", Year, Week, Day);
// And even a DateTimeToISO8601() function:
// http://docwiki.embarcadero.com/Libraries/en/System.DateUtils.DateToISO8601
String s = DateTimeToISO8601(Now());

Br,
Ted

Edited by: Ted Lyngmo on Feb 2, 2018 7:20 PM
Remy Lebeau (Te...


Posts: 9,447
Registered: 12/23/01
Re: UTC Time [Edit]  
Click to report abuse...   Click to reply to this thread Reply
  Posted: Feb 5, 2018 11:27 AM   in response to: Ted Lyngmo in response to: Ted Lyngmo
Ted Lyngmo wrote:

What TDateTime could do to offer superiority is a strftime() function
with a means of telling its user [anything from mere copy constructor
to a programmer] how much memory it needs to allocate - just be C++
about it.

The strftime standard is pretty clear nowadays: "This function
acts like an a** if you don't supply a buffer large enough".
Brilliant...

That is not Embarcadero's fault. Take it up with the C and C++
standards committees to decide. Even Microsoft's implementation of
strftime() doesn't allow the destination buffer to be NULL/0-bytes for
calculating a buffer size:

https://msdn.microsoft.com/en-us/library/fe06s4ak.aspx

This function validates its parameters. If strDest, format, ortimeptr
is a null pointer, or if the tm data structure addressed by timeptr is
invalid (for example, if it contains out of range values for the time
or date), or if the format string contains an invalid formatting code,
the invalid parameter handler is invoked, as described in Parameter
Validation. If execution is allowed to continue, the function returns 0
and sets errno to EINVAL.

Where the Win32 API has succeeded for ~20-30 years by just supplying
no memory to a function to ask what it needs, that part became a
mystery for people deciding strftime's response.

Microsoft doesn't control how the C/C++ committees decide to implement
the C/C++ languages and standard libraries.

In order to calculate the exact malloc, you'll have to perform the
strftime calculations yourself. If in an embedded environment ... 1
byte? ... 2?

Most Win32 API functions that are allowed to return a calculated length
for a subsequent memory allocation will return a value that is in terms
of the data type the allocated memory will hold. 8-bit bytes for byte
arrays and ANSI strings, 16-bit chars for Unicode strings. So, it is
not that hard to calculate a malloc() size (you shouldn't be using
malloc() in C++ to begin with, though):

length = ...;
buffer = malloc(length * sizeof(buffer element type));


On the other hand, most of the components of a strftime() format string
have predictable output sizes, so it is not hard to just preallocate
the buffer ahead of time based on which components you use in your
format string.

--
Remy Lebeau (TeamB)
Ted Lyngmo

Posts: 117
Registered: 10/3/06
Re: UTC Time [Edit]  
Click to report abuse...   Click to reply to this thread Reply
  Posted: Feb 16, 2018 7:47 PM   in response to: Remy Lebeau (Te... in response to: Remy Lebeau (Te...
What I failed to emphasize:

The strftime standard is pretty clear nowadays: "This function acts like an a** if you don't supply a buffer large enough".
Brilliant... Where the Win32 API has succeeded for ~20-30 years by just supplying no memory to a function to ask what it needs

What I meant to say is that I do not actually like that way strftime behaves in the situations I described above - and I do promote the Win32 API:s behaviour in these cases.

Br,,
Ted

Edited by: Ted Lyngmo on Feb 16, 2018 7:49 PM
Legend
Helpful Answer (5 pts)
Correct Answer (10 pts)

Server Response from: ETNAJIVE02