mirror of
https://github.com/php/php-src.git
synced 2025-08-15 13:38:49 +02:00
pdo_firebird: Formatting time zone types
As a follow-up to the commit which introduced support for Firebird 4.0+ data types[1], we add support for formats for types with time zones. Since this uses the newer Firebird C++ API, pdo_firebird now requires a C++ compiler to be built. [1] <https://github.com/php/php-src/pull/14897> Co-authored-by: Christoph M. Becker <cmbecker69@gmx.de> Closes GH-15230.
This commit is contained in:
parent
5478d4b2c1
commit
225034dbbc
10 changed files with 318 additions and 16 deletions
3
NEWS
3
NEWS
|
@ -50,6 +50,9 @@ PHP NEWS
|
|||
deprecated. As the MYSQLI_STORE_RESULT_COPY_DATA constant was only used in
|
||||
conjunction with this function it has also been deprecated. (Girgias)
|
||||
|
||||
- PDO_Firebird:
|
||||
. Support proper formatting of time zone types. (sim1984)
|
||||
|
||||
- PHPDBG:
|
||||
. array out of bounds, stack overflow handled for segfault handler on windows.
|
||||
(David Carlier)
|
||||
|
|
|
@ -121,6 +121,8 @@ PHP 8.4 UPGRADE NOTES
|
|||
have been changed to set value as a bool.
|
||||
|
||||
- PDO_FIREBIRD:
|
||||
. Since some Firebird C++ APIs are used now, this extension requires a C++
|
||||
compiler to be built.
|
||||
. getAttribute, ATTR_AUTOCOMMIT has been changed to get the value as a bool.
|
||||
|
||||
- PDO_MYSQL:
|
||||
|
|
|
@ -45,9 +45,24 @@ if test "$PHP_PDO_FIREBIRD" != "no"; then
|
|||
|
||||
PHP_CHECK_PDO_INCLUDES
|
||||
|
||||
|
||||
PHP_PDO_FIREBIRD_COMMON_FLAGS=""
|
||||
PHP_NEW_EXTENSION([pdo_firebird],
|
||||
[pdo_firebird.c firebird_driver.c firebird_statement.c],
|
||||
[$ext_shared])
|
||||
[$ext_shared],,
|
||||
[$PHP_PDO_FIREBIRD_COMMON_FLAGS],
|
||||
[cxx])
|
||||
PHP_SUBST([PDO_FIREBIRD_SHARED_LIBADD])
|
||||
PHP_ADD_EXTENSION_DEP(pdo_firebird, pdo)
|
||||
|
||||
PHP_PDO_FIREBIRD_CXX_SOURCES="pdo_firebird_utils.cpp"
|
||||
|
||||
PHP_REQUIRE_CXX()
|
||||
PHP_CXX_COMPILE_STDCXX(11, mandatory, PHP_PDO_FIREBIRD_STDCXX)
|
||||
PHP_PDO_FIREBIRD_CXX_FLAGS="$PHP_PDO_FIREBIRD_COMMON_FLAGS $PHP_PDO_FIREBIRD_STDCXX"
|
||||
|
||||
PHP_ADD_SOURCES([$ext_dir],
|
||||
[$PHP_PDO_FIREBIRD_CXX_SOURCES],
|
||||
[$PHP_PDO_FIREBIRD_CXX_FLAGS])
|
||||
|
||||
fi
|
||||
|
|
|
@ -10,7 +10,8 @@ if (PHP_PDO_FIREBIRD != "no") {
|
|||
PHP_PHP_BUILD + "\\include\\interbase;" + PHP_PHP_BUILD + "\\interbase\\include;" + PHP_PDO_FIREBIRD)
|
||||
) {
|
||||
|
||||
EXTENSION("pdo_firebird", "pdo_firebird.c firebird_driver.c firebird_statement.c");
|
||||
EXTENSION("pdo_firebird", "pdo_firebird.c firebird_driver.c firebird_statement.c pdo_firebird_utils.cpp");
|
||||
ADD_FLAG("CFLAGS_PDO_FIREBIRD", "/EHsc");
|
||||
} else {
|
||||
WARNING("pdo_firebird not enabled; libraries and headers not found");
|
||||
}
|
||||
|
|
|
@ -30,6 +30,7 @@
|
|||
#include "ext/pdo/php_pdo_driver.h"
|
||||
#include "php_pdo_firebird.h"
|
||||
#include "php_pdo_firebird_int.h"
|
||||
#include "pdo_firebird_utils.h"
|
||||
|
||||
static int php_firebird_alloc_prepare_stmt(pdo_dbh_t*, const zend_string*, XSQLDA*, isc_stmt_handle*,
|
||||
HashTable*);
|
||||
|
@ -462,14 +463,13 @@ static int php_firebird_preprocess(const zend_string* sql, char* sql_out, HashTa
|
|||
|
||||
#if FB_API_VER >= 40
|
||||
/* set coercing a data type */
|
||||
static void set_coercing_data_type(XSQLDA* sqlda)
|
||||
static void set_coercing_input_data_types(XSQLDA* sqlda)
|
||||
{
|
||||
/* Data types introduced in Firebird 4.0 are difficult to process using the Firebird Legacy API. */
|
||||
/* These data types include DECFLOAT(16), DECFLOAT(34), INT128 (NUMERIC/DECIMAL(38, x)), */
|
||||
/* TIMESTAMP WITH TIME ZONE, and TIME WITH TIME ZONE. In any case, at least the first three data types */
|
||||
/* can only be mapped to strings. The last two too, but for them it is potentially possible to set */
|
||||
/* the display format, as is done for TIMESTAMP. This function allows you to ensure minimal performance */
|
||||
/* of queries if they contain columns and parameters of the above types. */
|
||||
/* TIMESTAMP WITH TIME ZONE, and TIME WITH TIME ZONE. */
|
||||
/* This function allows you to ensure minimal performance */
|
||||
/* of queries if they contain parameters of the above types. */
|
||||
unsigned int i;
|
||||
short dtype;
|
||||
short nullable;
|
||||
|
@ -485,7 +485,7 @@ static void set_coercing_data_type(XSQLDA* sqlda)
|
|||
break;
|
||||
|
||||
case SQL_DEC16:
|
||||
var->sqltype = SQL_VARYING + nullable;
|
||||
var->sqltype = SQL_VARYING + nullable;
|
||||
var->sqllen = 24;
|
||||
break;
|
||||
|
||||
|
@ -503,8 +503,65 @@ static void set_coercing_data_type(XSQLDA* sqlda)
|
|||
var->sqltype = SQL_VARYING + nullable;
|
||||
var->sqllen = 46;
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void set_coercing_output_data_types(XSQLDA* sqlda)
|
||||
{
|
||||
/* Data types introduced in Firebird 4.0 are difficult to process using the Firebird Legacy API. */
|
||||
/* These data types include DECFLOAT(16), DECFLOAT(34), INT128 (NUMERIC/DECIMAL(38, x)). */
|
||||
/* In any case, at this data types can only be mapped to strings. */
|
||||
/* This function allows you to ensure minimal performance of queries if they contain columns of the above types. */
|
||||
unsigned int i;
|
||||
short dtype;
|
||||
short nullable;
|
||||
XSQLVAR* var;
|
||||
unsigned fb_client_version = fb_get_client_version();
|
||||
unsigned fb_client_major_version = (fb_client_version >> 8) & 0xFF;
|
||||
for (i=0, var = sqlda->sqlvar; i < sqlda->sqld; i++, var++) {
|
||||
dtype = (var->sqltype & ~1); /* drop flag bit */
|
||||
nullable = (var->sqltype & 1);
|
||||
switch(dtype) {
|
||||
case SQL_INT128:
|
||||
var->sqltype = SQL_VARYING + nullable;
|
||||
var->sqllen = 46;
|
||||
var->sqlscale = 0;
|
||||
break;
|
||||
|
||||
case SQL_DEC16:
|
||||
var->sqltype = SQL_VARYING + nullable;
|
||||
var->sqllen = 24;
|
||||
break;
|
||||
|
||||
case SQL_DEC34:
|
||||
var->sqltype = SQL_VARYING + nullable;
|
||||
var->sqllen = 43;
|
||||
break;
|
||||
|
||||
case SQL_TIMESTAMP_TZ:
|
||||
if (fb_client_major_version < 4) {
|
||||
/* If the client version is below 4.0, then it is impossible to handle time zones natively, */
|
||||
/* so we convert these types to a string. */
|
||||
var->sqltype = SQL_VARYING + nullable;
|
||||
var->sqllen = 58;
|
||||
}
|
||||
break;
|
||||
|
||||
case SQL_TIME_TZ:
|
||||
if (fb_client_major_version < 4) {
|
||||
/* If the client version is below 4.0, then it is impossible to handle time zones natively, */
|
||||
/* so we convert these types to a string. */
|
||||
var->sqltype = SQL_VARYING + nullable;
|
||||
var->sqllen = 46;
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -657,7 +714,7 @@ static bool firebird_handle_preparer(pdo_dbh_t *dbh, zend_string *sql, /* {{{ */
|
|||
|
||||
#if FB_API_VER >= 40
|
||||
/* set coercing a data type */
|
||||
set_coercing_data_type(&S->out_sqlda);
|
||||
set_coercing_output_data_types(&S->out_sqlda);
|
||||
#endif
|
||||
|
||||
/* allocate the input descriptors */
|
||||
|
@ -676,7 +733,7 @@ static bool firebird_handle_preparer(pdo_dbh_t *dbh, zend_string *sql, /* {{{ */
|
|||
|
||||
#if FB_API_VER >= 40
|
||||
/* set coercing a data type */
|
||||
set_coercing_data_type(S->in_sqlda);
|
||||
set_coercing_input_data_types(S->in_sqlda);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
@ -1245,7 +1302,8 @@ static int pdo_firebird_get_attribute(pdo_dbh_t *dbh, zend_long attr, zval *val)
|
|||
ZVAL_STRING(val, tmp);
|
||||
return 1;
|
||||
}
|
||||
return -1;
|
||||
/* TODO Check this is correct? */
|
||||
ZEND_FALLTHROUGH;
|
||||
|
||||
case PDO_ATTR_FETCH_TABLE_NAMES:
|
||||
ZVAL_BOOL(val, H->fetch_table_names);
|
||||
|
|
|
@ -25,6 +25,7 @@
|
|||
#include "ext/pdo/php_pdo_driver.h"
|
||||
#include "php_pdo_firebird.h"
|
||||
#include "php_pdo_firebird_int.h"
|
||||
#include "pdo_firebird_utils.h"
|
||||
|
||||
#include <time.h>
|
||||
|
||||
|
@ -64,6 +65,78 @@ static zend_always_inline ISC_QUAD php_get_isc_quad_from_sqldata(const ISC_SCHAR
|
|||
READ_AND_RETURN_USING_MEMCPY(ISC_QUAD, sqldata);
|
||||
}
|
||||
|
||||
#if FB_API_VER >= 40
|
||||
|
||||
static zend_always_inline ISC_TIME_TZ php_get_isc_time_tz_from_sqldata(const ISC_SCHAR *sqldata)
|
||||
{
|
||||
READ_AND_RETURN_USING_MEMCPY(ISC_TIME_TZ, sqldata);
|
||||
}
|
||||
|
||||
static zend_always_inline ISC_TIMESTAMP_TZ php_get_isc_timestamp_tz_from_sqldata(const ISC_SCHAR *sqldata)
|
||||
{
|
||||
READ_AND_RETURN_USING_MEMCPY(ISC_TIMESTAMP_TZ, sqldata);
|
||||
}
|
||||
|
||||
/* fetch formatted time with time zone */
|
||||
static int get_formatted_time_tz(pdo_stmt_t *stmt, const ISC_TIME_TZ* timeTz, zval *result)
|
||||
{
|
||||
pdo_firebird_stmt *S = (pdo_firebird_stmt*)stmt->driver_data;
|
||||
unsigned hours = 0, minutes = 0, seconds = 0, fractions = 0;
|
||||
char timeZoneBuffer[40] = {0};
|
||||
char *fmt;
|
||||
struct tm t;
|
||||
ISC_TIME time;
|
||||
char timeBuf[80] = {0};
|
||||
char timeTzBuf[124] = {0};
|
||||
if (fb_decode_time_tz(S->H->isc_status, timeTz, &hours, &minutes, &seconds, &fractions, sizeof(timeZoneBuffer), timeZoneBuffer)) {
|
||||
return 1;
|
||||
}
|
||||
time = fb_encode_time(hours, minutes, seconds, fractions);
|
||||
isc_decode_sql_time(&time, &t);
|
||||
fmt = S->H->time_format ? S->H->time_format : PDO_FB_DEF_TIME_FMT;
|
||||
|
||||
size_t len = strftime(timeBuf, sizeof(timeBuf), fmt, &t);
|
||||
if (len == 0) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
size_t time_tz_len = sprintf(timeTzBuf, "%s %s", timeBuf, timeZoneBuffer);
|
||||
ZVAL_STRINGL(result, timeTzBuf, time_tz_len);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* fetch formatted timestamp with time zone */
|
||||
static int get_formatted_timestamp_tz(pdo_stmt_t *stmt, const ISC_TIMESTAMP_TZ* timestampTz, zval *result)
|
||||
{
|
||||
pdo_firebird_stmt *S = (pdo_firebird_stmt*)stmt->driver_data;
|
||||
unsigned year, month, day, hours, minutes, seconds, fractions;
|
||||
char timeZoneBuffer[40] = {0};
|
||||
char *fmt;
|
||||
struct tm t;
|
||||
ISC_TIMESTAMP ts;
|
||||
char timestampBuf[80] = {0};
|
||||
char timestampTzBuf[124] = {0};
|
||||
if (fb_decode_timestamp_tz(S->H->isc_status, timestampTz, &year, &month, &day, &hours, &minutes, &seconds, &fractions, sizeof(timeZoneBuffer), timeZoneBuffer)) {
|
||||
return 1;
|
||||
}
|
||||
ts.timestamp_date = fb_encode_date(year, month, day);
|
||||
ts.timestamp_time = fb_encode_time(hours, minutes, seconds, fractions);
|
||||
isc_decode_timestamp(&ts, &t);
|
||||
|
||||
fmt = S->H->timestamp_format ? S->H->timestamp_format : PDO_FB_DEF_TIMESTAMP_FMT;
|
||||
|
||||
size_t len = strftime(timestampBuf, sizeof(timestampBuf), fmt, &t);
|
||||
if (len == 0) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
size_t timestamp_tz_len = sprintf(timestampTzBuf, "%s %s", timestampBuf, timeZoneBuffer);
|
||||
ZVAL_STRINGL(result, timestampTzBuf, timestamp_tz_len);
|
||||
return 0;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
/* free the allocated space for passing field values to the db and back */
|
||||
static void php_firebird_free_sqlda(XSQLDA const *sqlda) /* {{{ */
|
||||
{
|
||||
|
@ -494,6 +567,16 @@ static int pdo_firebird_stmt_get_col(
|
|||
size_t len = strftime(buf, sizeof(buf), fmt, &t);
|
||||
ZVAL_STRINGL(result, buf, len);
|
||||
break;
|
||||
#if FB_API_VER >= 40
|
||||
case SQL_TIME_TZ: {
|
||||
ISC_TIME_TZ time = php_get_isc_time_tz_from_sqldata(var->sqldata);
|
||||
return get_formatted_time_tz(stmt, &time, result);
|
||||
}
|
||||
case SQL_TIMESTAMP_TZ: {
|
||||
ISC_TIMESTAMP_TZ ts = php_get_isc_timestamp_tz_from_sqldata(var->sqldata);
|
||||
return get_formatted_timestamp_tz(stmt, &ts, result);
|
||||
}
|
||||
#endif
|
||||
case SQL_BLOB: {
|
||||
ISC_QUAD quad = php_get_isc_quad_from_sqldata(var->sqldata);
|
||||
return php_firebird_fetch_blob(stmt, colno, result, &quad);
|
||||
|
|
92
ext/pdo_firebird/pdo_firebird_utils.cpp
Normal file
92
ext/pdo_firebird/pdo_firebird_utils.cpp
Normal file
|
@ -0,0 +1,92 @@
|
|||
/*
|
||||
+----------------------------------------------------------------------+
|
||||
| Copyright (c) The PHP Group |
|
||||
+----------------------------------------------------------------------+
|
||||
| This source file is subject to version 3.01 of the PHP license, |
|
||||
| that is bundled with this package in the file LICENSE, and is |
|
||||
| available through the world-wide-web at the following url: |
|
||||
| https://www.php.net/license/3_01.txt |
|
||||
| If you did not receive a copy of the PHP license and are unable to |
|
||||
| obtain it through the world-wide-web, please send a note to |
|
||||
| license@php.net so we can mail you a copy immediately. |
|
||||
+----------------------------------------------------------------------+
|
||||
| Author: Simonov Denis <sim-mail@list.ru> |
|
||||
+----------------------------------------------------------------------+
|
||||
*/
|
||||
|
||||
#include "pdo_firebird_utils.h"
|
||||
#include <firebird/Interface.h>
|
||||
#include <cstring>
|
||||
|
||||
static void fb_copy_status(const ISC_STATUS* from, ISC_STATUS* to, size_t maxLength)
|
||||
{
|
||||
for(size_t i=0; i < maxLength; ++i) {
|
||||
memcpy(to + i, from + i, sizeof(ISC_STATUS));
|
||||
if (from[i] == isc_arg_end) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Returns the client version. 0 bytes are minor version, 1 bytes are major version. */
|
||||
extern "C" unsigned fb_get_client_version(void)
|
||||
{
|
||||
Firebird::IMaster* master = Firebird::fb_get_master_interface();
|
||||
Firebird::IUtil* util = master->getUtilInterface();
|
||||
return util->getClientVersion();
|
||||
}
|
||||
|
||||
extern "C" ISC_TIME fb_encode_time(unsigned hours, unsigned minutes, unsigned seconds, unsigned fractions)
|
||||
{
|
||||
Firebird::IMaster* master = Firebird::fb_get_master_interface();
|
||||
Firebird::IUtil* util = master->getUtilInterface();
|
||||
return util->encodeTime(hours, minutes, seconds, fractions);
|
||||
}
|
||||
|
||||
extern "C" ISC_DATE fb_encode_date(unsigned year, unsigned month, unsigned day)
|
||||
{
|
||||
Firebird::IMaster* master = Firebird::fb_get_master_interface();
|
||||
Firebird::IUtil* util = master->getUtilInterface();
|
||||
return util->encodeDate(year, month, day);
|
||||
}
|
||||
|
||||
#if FB_API_VER >= 40
|
||||
|
||||
/* Decodes a time with time zone into its time components. */
|
||||
extern "C" ISC_STATUS fb_decode_time_tz(ISC_STATUS* isc_status, const ISC_TIME_TZ* timeTz, unsigned* hours, unsigned* minutes, unsigned* seconds, unsigned* fractions,
|
||||
unsigned timeZoneBufferLength, char* timeZoneBuffer)
|
||||
{
|
||||
Firebird::IMaster* master = Firebird::fb_get_master_interface();
|
||||
Firebird::IUtil* util = master->getUtilInterface();
|
||||
Firebird::IStatus* status = master->getStatus();
|
||||
Firebird::CheckStatusWrapper st(status);
|
||||
util->decodeTimeTz(&st, timeTz, hours, minutes, seconds, fractions,
|
||||
timeZoneBufferLength, timeZoneBuffer);
|
||||
if (st.hasData()) {
|
||||
fb_copy_status((const ISC_STATUS*)st.getErrors(), isc_status, 20);
|
||||
}
|
||||
status->dispose();
|
||||
return isc_status[1];
|
||||
}
|
||||
|
||||
/* Decodes a timestamp with time zone into its date and time components */
|
||||
extern "C" ISC_STATUS fb_decode_timestamp_tz(ISC_STATUS* isc_status, const ISC_TIMESTAMP_TZ* timestampTz,
|
||||
unsigned* year, unsigned* month, unsigned* day,
|
||||
unsigned* hours, unsigned* minutes, unsigned* seconds, unsigned* fractions,
|
||||
unsigned timeZoneBufferLength, char* timeZoneBuffer)
|
||||
{
|
||||
Firebird::IMaster* master = Firebird::fb_get_master_interface();
|
||||
Firebird::IUtil* util = master->getUtilInterface();
|
||||
Firebird::IStatus* status = master->getStatus();
|
||||
Firebird::CheckStatusWrapper st(status);
|
||||
util->decodeTimeStampTz(&st, timestampTz, year, month, day,
|
||||
hours, minutes, seconds, fractions,
|
||||
timeZoneBufferLength, timeZoneBuffer);
|
||||
if (st.hasData()) {
|
||||
fb_copy_status((const ISC_STATUS*)st.getErrors(), isc_status, 20);
|
||||
}
|
||||
status->dispose();
|
||||
return isc_status[1];
|
||||
}
|
||||
|
||||
#endif
|
48
ext/pdo_firebird/pdo_firebird_utils.h
Normal file
48
ext/pdo_firebird/pdo_firebird_utils.h
Normal file
|
@ -0,0 +1,48 @@
|
|||
/*
|
||||
+----------------------------------------------------------------------+
|
||||
| Copyright (c) The PHP Group |
|
||||
+----------------------------------------------------------------------+
|
||||
| This source file is subject to version 3.01 of the PHP license, |
|
||||
| that is bundled with this package in the file LICENSE, and is |
|
||||
| available through the world-wide-web at the following url: |
|
||||
| https://www.php.net/license/3_01.txt |
|
||||
| If you did not receive a copy of the PHP license and are unable to |
|
||||
| obtain it through the world-wide-web, please send a note to |
|
||||
| license@php.net so we can mail you a copy immediately. |
|
||||
+----------------------------------------------------------------------+
|
||||
| Author: Simonov Denis <sim-mail@list.ru> |
|
||||
+----------------------------------------------------------------------+
|
||||
*/
|
||||
|
||||
#ifndef PDO_FIREBIRD_UTILS_H
|
||||
#define PDO_FIREBIRD_UTILS_H
|
||||
|
||||
#include <ibase.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
unsigned fb_get_client_version(void);
|
||||
|
||||
ISC_TIME fb_encode_time(unsigned hours, unsigned minutes, unsigned seconds, unsigned fractions);
|
||||
|
||||
ISC_DATE fb_encode_date(unsigned year, unsigned month, unsigned day);
|
||||
|
||||
#if FB_API_VER >= 40
|
||||
|
||||
ISC_STATUS fb_decode_time_tz(ISC_STATUS* isc_status, const ISC_TIME_TZ* timeTz, unsigned* hours, unsigned* minutes, unsigned* seconds, unsigned* fractions,
|
||||
unsigned timeZoneBufferLength, char* timeZoneBuffer);
|
||||
|
||||
ISC_STATUS fb_decode_timestamp_tz(ISC_STATUS* isc_status, const ISC_TIMESTAMP_TZ* timestampTz,
|
||||
unsigned* year, unsigned* month, unsigned* day,
|
||||
unsigned* hours, unsigned* minutes, unsigned* seconds, unsigned* fractions,
|
||||
unsigned timeZoneBufferLength, char* timeZoneBuffer);
|
||||
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* PDO_FIREBIRD_UTILS_H */
|
|
@ -54,9 +54,9 @@ echo "\ndone\n";
|
|||
"N": "123.97",
|
||||
"N2": "123.97",
|
||||
"TS": "2024-05-04 12:59:34",
|
||||
"TS_TZ": "%s 12:59:34.2390 Europe\/Moscow",
|
||||
"TS_TZ": "2024-05-04 12:59:34 Europe\/Moscow",
|
||||
"T": "12:59:34",
|
||||
"T_TZ": "12:59:34.2390 Europe\/Moscow",
|
||||
"T_TZ": "12:59:34 Europe\/Moscow",
|
||||
"DF16": "1.128",
|
||||
"DF34": "1.128"
|
||||
}
|
||||
|
|
|
@ -49,8 +49,8 @@ echo "\ndone\n";
|
|||
"I128": "12",
|
||||
"N1": "12.34",
|
||||
"N2": "12.34",
|
||||
"TS_TZ": "%s 12:59:34.2390 Europe\/Moscow",
|
||||
"T_TZ": "12:59:00.0000 Europe\/Moscow",
|
||||
"TS_TZ": "2024-05-04 12:59:34 Europe\/Moscow",
|
||||
"T_TZ": "12:59:00 Europe\/Moscow",
|
||||
"DF16": "12.34",
|
||||
"DF34": "12.34"
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue