DAW JSON Link
|
Timestmaps are common in JSON datasets. DAW JSON Link has a convienience type to serialize/deserialize ISO8601 timestamps.
The above JSON object consists of a 2 string members, where the second stores an ISO8601 combinded representation timestamp.
To see a working example using this code, refer to cookbook_dates1_test.cpp
Below is code that code serialize/deserialize the above JSON using the json_date
class.
The above json is like the first example, but the timestamp format is not iso8601. It is the date format used in some twitter JSON apis. The string member will be a json_string
and the timestmap will use json_custom
. This example is more involved and also outlines using json_custom
to work with data that does not fit the other mappings.
json_custom
requires a callable FromJsonConverter and a callable ToJsonConverter type to convert to T
from a std::string_view
and to a string like type from a T
.
The To and From Converters can be the same type with different overloads for operator()
. T will be a std::chrono::time_point<std::chrono::system_clock, std::chrono::milliseconds>
.
Too see a working example using this code, refer to cookbook_dates2_test.cpp
A time_point can be encoded into JSON a the number of seconds since epoch(Jan 1, 1970 @ 12:00:00am ).
This example will use the constructor of the class to construct the time_point
from the integer. Otherwise, a json_custom
type could be used here too. It demonstrates using a constructor to do the data conversions, along with to_json_data
to reverse the conversion. Another alternative is to use the Constructor
template argument to do the conversion of the integer to the time_point
. The dateAdded
member shows parsing strings into numbers. This is often done as numbers in JSON are double and can only hold integers as large as 2^53.
Too see a working example using this code, refer to cookbook_dates3_test.cpp
In some older MS implementations of AJAX, dates were encoded like
where the first number is the number of seconds since UNIX epoch, and then, optionally, followed by an offset.
Taking the first example, modified the time to use the MS AJAX format, the timestamp only has 1s resolution and is a number.
When parsing the timestamp
member we need to skip the first 6 characters, optionally verifying it says "/DATE(</tt>. Then parse the number and add it to a <tt>std::chrono</tt> timestamp with the time of Unix Epoc, Midight January 1, 1970.
Too see a working example using this code, refer to <a href="../../tests/src/cookbook_dates4_test.cpp" >cookbook_dates4_test.cpp</a>
@icode{c} ++
using timepoint_t = std::chrono::time_point<std::chrono::system_clock, std::chrono::milliseconds>;
struct TimestampConverter {
timepoint_t operator( )( std::string_view sv ) const {
auto sv2 = daw::string_view( sv.data( ), sv.size( ) );
daw::string_view const prefix = "/DATE(";
daw::string_view const suffix = ")/";
daw_json_assert( sv2.starts_with( prefix ), "Unexpected date format" );
daw_json_assert( sv2.ends_with( suffix ), "Unexpected date format" );
sv2.remove_prefix( prefix.size( ) );
sv2.remove_suffix( suffix.size( ) );
int64_t val =
daw::json::from_json<int64_t, daw::json::NoCommentSkippingPolicyChecked,
true>( sv2 );
const auto epoch =
daw::json::datetime::civil_to_time_point( 1970, 1, 1, 0, 0, 0, 0 );
return epoch + std::chrono::seconds( val );
}
// Same class as above, but the JSON encoding differs
struct MyClass4 {
std::string name;
timepoint_t timestamp;
};
namespace daw::json {
template<>
struct json_data_contract<MyClass4> {
using type = json_member_list<
json_string<"name">,
json_custom<"timestamp", timepoint_t, TimestampConverter, TimestampConverter > >;
static inline auto to_json_data( MyClass4 const & v ) { return std::forward_as_tuple( v.name, v.timestamp ); } }; } // ... timepoint_t my_timepoint = daw::json::from_json<MyClass4>( json_document );