【问题标题】:Snowflake/javascript datetime format changes during iterationSnowflake/javascript 日期时间格式在迭代期间发生变化
【发布时间】:2022-01-13 02:40:42
【问题描述】:
 Column_name   DateType           Actual data(in table)   
 CALDT         TIMESTAMP_LTZ(9)   2021-12-07 15:17:04.673 -0800

Javascript 将上述日期转换为类似“Tue Dec 07 2021 14:52:12 GMT-0800 (Pacific Standard Time)”的内容

这里是javascript代码

         var caldt = " SELECT CALDT"
         caldt += "  FROM INFORMATION_SCHEMA.TABLES "
         caldt += " WHERE TABLE_SCHEMA = " + String.fromCharCode(39)  + TARGET_SCHEMA + String.fromCharCode(39)
         caldt += "   AND TABLE_NAME   = " + String.fromCharCode(39)  +  TARGET_TABLE + String.fromCharCode(39);
                 
    var cal_statement = snowflake.createStatement({sqlText: caldt });
    var cal_resultSet = cal_statement.execute();
    var cal_column_name_array = "";    
      
    while (cal_resultSet .next()) {
        var cal_column_name =cal_resultSet .getColumnValue(1);
       **cal_column_name_array = cal_column_name_array += String.fromCharCode(39) + cal_column_name + String.fromCharCode(39) + ", "    ;        
    }
 cal_column_name_array = cal_column_name_array.substring(0, cal_column_name_array.length-2);** 

上面**...**之间的代码正在修改时间戳

但是我需要获得相同的日期时间戳(2021-12-07 15:17:04.673 -0800)和

不是“2021 年 12 月 7 日星期二 14:52:12 GMT-0800(太平洋标准时间)”

如何格式化 javascript 迭代代码以返回日期时间/时间戳。 谢谢

【问题讨论】:

    标签: javascript javascript-objects snowflake-cloud-data-platform


    【解决方案1】:

    我已经测试过了,如果你强制你的雪花查询中的时间戳列是字符串,那么它将避免你的问题。

    请参阅下面的测试用例。

    1. 准备数据(注意时间戳列需要是 TIMESTAMP_TZ 类型,否则它不会保留原始字符串,因为它会被转换为本地时区或无时区,具体取决于您的设置):
    create or replace table date_table(
        date_string string, 
        date_time_tz timestamp_tz,
        date_time_ntz timestamp_ntz,
        date_time_ltz timestamp_ltz
    );
    
    insert into date_table values 
        ('2021-12-07 15:17:04.673 -0800', 
         '2021-12-07 15:17:04.673 -0800',
         '2021-12-07 15:17:04.673 -0800',
         '2021-12-07 15:17:04.673 -0800');
    
    1. 准备 SP:
    create or replace procedure test_date(query string)
    returns string
    language javascript
    as 
    $$
        var my_date = "";
        var cal_statement = snowflake.createStatement({sqlText: QUERY });
        var rs = cal_statement.execute();
        while (rs.next()) {
            
            my_date += '*' + rs.getColumnValue(1) + '*\n';
            my_date += '*' + rs.getColumnValue(2) + '*\n';
            my_date += '*' + rs.getColumnValue(3) + '*\n';
            my_date += '*' + rs.getColumnValue(4) + '*';
        }
        
        return my_date;
    $$;
    
    1. 使用时间戳值调用 SP(它将显示您的问题):
    call test_date('select * from date_table');
    
    +------------------------------------------------------------------+
    | TEST_DATE                                                        |
    |------------------------------------------------------------------|
    | *2021-12-07 15:17:04.673 -0800*                                  |
    | *Tue Dec 07 2021 23:17:04 GMT+0000 (Coordinated Universal Time)* |
    | *Tue Dec 07 2021 15:17:04 GMT+0000 (Coordinated Universal Time)* |
    | *Tue Dec 07 2021 23:17:04 GMT+0000 (Coordinated Universal Time)* |
    +------------------------------------------------------------------+
    
    1. 通过将时间戳值转换为 STRING(您想要的)来调用 SP:
    call test_date('select date_string, date_time_tz::string, date_time_ntz::string, date_time_ltz::string from date_table');
    
    +---------------------------------+
    | TEST_DATE                       |
    |---------------------------------|
    | *2021-12-07 15:17:04.673 -0800* |
    | *2021-12-07 15:17:04.673 -0800* |
    | *2021-12-07 15:17:04.673000000* |
    | *2021-12-07 23:17:04.673 Z*     |
    +---------------------------------+
    

    因此,您需要确保使用 timestamp_tz 数据类型并转换为字符串,这应该有助于解决您的问题。

    更新

    我们可以使用getColumnValueAsString() 代替ResultSet 对象的getColumnValue() 在JS 内部而不是在SQL 级别将值从TIMESTAMP 转换为STRING。

    https://docs.snowflake.com/en/sql-reference/stored-procedures-api.html#getColumnValueAsString

    所以更新的SP如下:

    create or replace procedure test_date(query string)
    returns string
    language javascript
    as 
    $$
        var my_date = "";
        var cal_statement = snowflake.createStatement({sqlText: QUERY });
        var rs = cal_statement.execute();
        while (rs.next()) {
            
            my_date += '*' + rs.getColumnValueAsString(1) + '*\n';
            my_date += '*' + rs.getColumnValueAsString(2) + '*\n';
            my_date += '*' + rs.getColumnValueAsString(3) + '*\n';
            my_date += '*' + rs.getColumnValueAsString(4) + '*';
        }
        
        return my_date;
    $$;
    

    然后我们就可以运行 SELECT *:

    call test_date('select * from date_table');
    
    +----------------------------------------+
    | TEST_DATE                              |
    |----------------------------------------|
    | *2021-12-07 15:17:04.673 -0800*        |
    | *2021-12-07 15:17:04.673000000 -08:00* |
    | *2021-12-07 15:17:04.673000000*        |
    | *2021-12-07 23:17:04.673000000*        |
    +----------------------------------------+
    

    我不知道是什么控制了毫秒部分的位数,因为 TIMESTAMP_%_OUTPUT_FORMAT 参数似乎无法控制它。

    如果需要,您可能需要手动删除尾随零。

    【讨论】:

    • 谢谢,当我检索 javascript my_date += '*' + rs.getColumnValue(1) + '*\n ';因为我需要在下面的另一个 sql 中使用时间戳值。我看到您在调用 SP 时将其作为输出参数,但我需要在 javascript/SP 中使用时间戳。这可能吗?
    • 更新了答案。
    【解决方案2】:

    返回以 ISO 格式格式化的日期的简化过程:

    create or replace procedure date_format()
    returns varchar not null
    language javascript
    as
    $$
    var caldt = "select current_timestamp() x;"
    var cal_statement = snowflake.createStatement({sqlText: caldt });
    var cal_resultSet = cal_statement.execute();
    
    while (cal_resultSet.next()) {
        return cal_resultSet.getColumnValue(1).toISOString();
    }
    $$;
    
    call date_format();
    

    使用.toISOString() 返回2021-12-08T05:04:26.000Z

    https://stackoverflow.com/a/13219636/132438 的答案包括额外格式的额外代码:

    new Date().toISOString().replace(/T/, ' ').replace(/\..+/, '')
    

    返回2012-11-04 14:55:45

    【讨论】:

    • 它返回“2021-12-07 22:52:12”而不是“2021-12-07 15:17:04.673 -0800”。我需要这个(2021-12-07 15:17:04.673 -0800)确切值或至少“2021-12-07 15:17:04.673”。这样我就可以比较日期。谢谢
    • 你在哪里比较日期?也许您也可以将其他日期转换为 UTC,以避免时区过于复杂。
    • 我没有展示整个 JS,但在下面我正在比较日期,这就是为什么拥有正确的日期格式很重要。它返回“2021-12-07 22:52:12”而不是“2021-12-07 15:17:04.673 -0800”。
    • 我可以帮你比较日期,如果你告诉我你比较日期的代码和两者的来源。
    • 不确定,为什么会出现这样的问题,从数据库中检索值。我认为“2021-12-07 22:52:12”与“2021-12-07 15:17:04.673 -0800”日期时间不同。比较是 sql 的一部分,其中 A.CalDT > B.CalDT 就是这样。如果日期格式不正确,那么显然会得出错误的结果。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-10-04
    • 1970-01-01
    • 2018-03-04
    • 2019-03-04
    相关资源
    最近更新 更多