从 ISO 8601 日期字符串转换为 BigQuery 时间戳时出错
Error when converting to BigQuery timestamp from ISO 8601 date string
我有一个 ISO 8601 日期字符串,格式如下:
String myIsoDateString = "2019-02-27T23:00:00.000Z"
我需要使用日期字符串作为查询的一部分我在 BigQuery 中 运行。我正在尝试使用 com.google.cloud.bigquery.QueryParameterValue
class 将其转换为 QueryParameterValue
,类型为 timestamp
,如下所示:
QueryParameterValue.timestamp(myIsoDateString)
这给了我一个错误:
java.lang.IllegalArgumentException: Invalid format: "2019-02-27T23:00:00.000Z" is malformed at "T23:00:00.000Z"
Eclipse 中时间戳方法的内联帮助指出:
Creates a QueryParameterValue object with a type of TIMESTAMP. Must be in the format"yyyy-MM-dd HH:mm:ss.SSSSSSZZ", e.g. "2014-08-19 12:41:35.220000+00:00".
如何将 myIsoDateString
转换为所需的格式?有没有我可以使用的更好的方法来处理从 ISO 8601 字符串到 BigQuery 中的时间戳的转换?
错误提示格式不正确:
"2019-02-27T23:00:00.000Z"
但是这个会是:
"yyyy-MM-dd HH:mm:ss.SSSSSSZZ"
尝试将日期和时间之间的 T
替换为
。
ISO 8601 与 SQL
ISO 8601 标准在中间使用 T
将年月日部分与时分秒部分分开。
SQL 样式在中间使用 SPACE 而不是 T
。
替换。
String input = "2019-02-27T23:00:00.000Z".replace( "T" , " " ) ;
QueryParameterValue.timestamp( input ) ;
同上去另一个方向。 java.time 类 在 parsing/generating 文本时默认使用 ISO 8601 格式。
String input = "2019-02-27 23:00:00.000Z".replace( " " , "T" ) ;
Instant instant = Instant.parse( input ) ;
ZonedDateTime zdt = instant.atZone( ZoneId.of( "Pacific/Auckland" ) ) ;
我希望 Felipe Hoffa 的答案能够奏效并给你你想要的:用 space 替换 T
。这里有一些其他建议。
明确: 虽然文档给出了一个非常清楚的预期字符串示例,但从错误消息和文档(下面的link,但你已经在 Eclipse 中得到了它)QueryParameterValue.timestamp
是否接受 Z
作为偏移量。如果我们想确定并更明确地提供所要求的格式(对于那些在您之后管理您的代码的人来说总是很好):
DateTimeFormatter timestampFormatter
= DateTimeFormatter.ofPattern("uuuu-MM-dd HH:mm:ss.SSSSSSxxx");
String myIsoDateString = "2019-02-27T23:00:00.000Z";
OffsetDateTime dateTime = OffsetDateTime.parse(myIsoDateString);
QueryParameterValue.timestamp(dateTime.format(timestampFormatter));
这会将字符串 2019-02-27 23:00:00.000000+00:00
传递给 timestamp
。
传递一个 long: timestamp
是一个带有 Long
参数的重载版本。同样,没有记录 long 值应该是多少。编辑:您自己的回答显示 timestamp(Long)
需要自纪元以来的微秒。没有任何不必要的精度损失风险的完全正确的转换方法是:
String myIsoDateString = "2019-02-27T23:00:00.000Z";
Instant dateTime = Instant.parse(myIsoDateString);
long microsecondsSinceEpoch = TimeUnit.SECONDS.toMicros(dateTime.getEpochSecond())
+ TimeUnit.NANOSECONDS.toMicros(dateTime.getNano());
QueryParameterValue.timestamp(microsecondsSinceEpoch);
值 1 551 308 400 000 000 传递给 timestamp
。
免责声明:我不是 BigQuery 用户。
链接
这个有效:
import org.joda.time.DateTime;
import org.joda.time.DateTimeZone;
将myIsoDateString
转换为微秒并将其存储为long
:
long myDateInMicroseconds = DateTime.parse(myIsoDateString).toDateTime(DateTimeZone.UTC).getMillis() * 1000;
然后将其作为参数传递给QueryParameterValue.timestamp:
QueryParameterValue.timestamp(myDateInMicroseconds)
任何想在 BigQuery 中解析 ISO 8601 的人(这个 post 是第一个 Google 结果),试试这个:
SELECT
PARSE_TIMESTAMP('%Y-%m-%dT%H:%M:%E*SZ', '2018-10-12T13:22:27.120Z')
我有一个 ISO 8601 日期字符串,格式如下:
String myIsoDateString = "2019-02-27T23:00:00.000Z"
我需要使用日期字符串作为查询的一部分我在 BigQuery 中 运行。我正在尝试使用 com.google.cloud.bigquery.QueryParameterValue
class 将其转换为 QueryParameterValue
,类型为 timestamp
,如下所示:
QueryParameterValue.timestamp(myIsoDateString)
这给了我一个错误:
java.lang.IllegalArgumentException: Invalid format: "2019-02-27T23:00:00.000Z" is malformed at "T23:00:00.000Z"
Eclipse 中时间戳方法的内联帮助指出:
Creates a QueryParameterValue object with a type of TIMESTAMP. Must be in the format"yyyy-MM-dd HH:mm:ss.SSSSSSZZ", e.g. "2014-08-19 12:41:35.220000+00:00".
如何将 myIsoDateString
转换为所需的格式?有没有我可以使用的更好的方法来处理从 ISO 8601 字符串到 BigQuery 中的时间戳的转换?
错误提示格式不正确:
"2019-02-27T23:00:00.000Z"
但是这个会是:
"yyyy-MM-dd HH:mm:ss.SSSSSSZZ"
尝试将日期和时间之间的 T
替换为 。
ISO 8601 与 SQL
ISO 8601 标准在中间使用 T
将年月日部分与时分秒部分分开。
SQL 样式在中间使用 SPACE 而不是 T
。
替换。
String input = "2019-02-27T23:00:00.000Z".replace( "T" , " " ) ;
QueryParameterValue.timestamp( input ) ;
同上去另一个方向。 java.time 类 在 parsing/generating 文本时默认使用 ISO 8601 格式。
String input = "2019-02-27 23:00:00.000Z".replace( " " , "T" ) ;
Instant instant = Instant.parse( input ) ;
ZonedDateTime zdt = instant.atZone( ZoneId.of( "Pacific/Auckland" ) ) ;
我希望 Felipe Hoffa 的答案能够奏效并给你你想要的:用 space 替换 T
。这里有一些其他建议。
明确: 虽然文档给出了一个非常清楚的预期字符串示例,但从错误消息和文档(下面的link,但你已经在 Eclipse 中得到了它)QueryParameterValue.timestamp
是否接受 Z
作为偏移量。如果我们想确定并更明确地提供所要求的格式(对于那些在您之后管理您的代码的人来说总是很好):
DateTimeFormatter timestampFormatter
= DateTimeFormatter.ofPattern("uuuu-MM-dd HH:mm:ss.SSSSSSxxx");
String myIsoDateString = "2019-02-27T23:00:00.000Z";
OffsetDateTime dateTime = OffsetDateTime.parse(myIsoDateString);
QueryParameterValue.timestamp(dateTime.format(timestampFormatter));
这会将字符串 2019-02-27 23:00:00.000000+00:00
传递给 timestamp
。
传递一个 long: timestamp
是一个带有 Long
参数的重载版本。同样,没有记录 long 值应该是多少。编辑:您自己的回答显示 timestamp(Long)
需要自纪元以来的微秒。没有任何不必要的精度损失风险的完全正确的转换方法是:
String myIsoDateString = "2019-02-27T23:00:00.000Z";
Instant dateTime = Instant.parse(myIsoDateString);
long microsecondsSinceEpoch = TimeUnit.SECONDS.toMicros(dateTime.getEpochSecond())
+ TimeUnit.NANOSECONDS.toMicros(dateTime.getNano());
QueryParameterValue.timestamp(microsecondsSinceEpoch);
值 1 551 308 400 000 000 传递给 timestamp
。
免责声明:我不是 BigQuery 用户。
链接
这个有效:
import org.joda.time.DateTime;
import org.joda.time.DateTimeZone;
将myIsoDateString
转换为微秒并将其存储为long
:
long myDateInMicroseconds = DateTime.parse(myIsoDateString).toDateTime(DateTimeZone.UTC).getMillis() * 1000;
然后将其作为参数传递给QueryParameterValue.timestamp:
QueryParameterValue.timestamp(myDateInMicroseconds)
任何想在 BigQuery 中解析 ISO 8601 的人(这个 post 是第一个 Google 结果),试试这个:
SELECT
PARSE_TIMESTAMP('%Y-%m-%dT%H:%M:%E*SZ', '2018-10-12T13:22:27.120Z')