我有一个ISO 8601日期字符串,其格式如下:
String myIsoDateString = "2019-02-27T23:00:00.000Z"
我需要在BigQuery中运行的查询中使用日期字符串。我正在尝试使用com.google.cloud.bigquery.QueryParameterValue
类将其转换为QueryParameterValue
类型的timestamp
,如下所示:
QueryParameterValue.timestamp(myIsoDateString)
这给了我一个错误:
java.lang.IllegalArgumentException: Invalid format: "2019-02-27T23:00:00.000Z" is malformed at "T23:00:00.000Z"
Eclipse中的timestamp方法的内联帮助指出:
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中的时间戳的转换吗?
答案 0 :(得分:3)
我希望Felipe Hoffa的答案能起作用,并给您您想要的东西:用空格替换T
。这里还有其他一些建议。
要明确:虽然文档提供了一个非常清晰的预期字符串示例,但从错误消息或文档中都不清楚(下面的链接,但是您已经在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
。
传递很长的时间:timestamp
是带有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用户。
答案 1 :(得分:1)
该错误表明这不是正确的格式:
"2019-02-27T23:00:00.000Z"
但这是:
"yyyy-MM-dd HH:mm:ss.SSSSSSZZ"
尝试将日期和时间之间的T
替换为。
答案 2 :(得分:1)
ISO 8601标准在中间使用T
将年月日部分与时分秒部分分开。
SQL样式在中间使用空格,而不是T
。
替换。
String input = "2019-02-27T23:00:00.000Z".replace( "T" , " " ) ;
QueryParameterValue.timestamp( input ) ;
Ditto用于其他方向。解析/生成文本时, java.time 类默认使用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" ) ) ;
答案 3 :(得分:0)
这有效:
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)
答案 4 :(得分:0)
对于任何试图在BigQuery中解析ISO 8601的人(这篇文章是Google的第一个结果),请尝试以下操作:
SELECT
PARSE_TIMESTAMP('%Y-%m-%dT%H:%M:%E*SZ', '2018-10-12T13:22:27.120Z')