我有一个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中的时间戳?
我希望得到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用户。
ISO 8601标准在中间使用T
将年 - 月 - 日部分与小时 - 分 - 秒部分分开。
SQL风格在中间使用SPACE而不是T
。
更换。
String input = "2019-02-27T23:00:00.000Z".replace( "T" , " " ) ;
QueryParameterValue.timestamp( input ) ;
同样朝着另一个方向前进。在解析/生成文本时,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" ) ) ;
错误说这不是正确的格式:
"2019-02-27T23:00:00.000Z"
但这个会是:
"yyyy-MM-dd HH:mm:ss.SSSSSSZZ"
尝试用T
替换日期和时间之间的。
这有效:
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的人(这篇文章是Google的第一个结果),试试这个:
SELECT
PARSE_TIMESTAMP('%Y-%m-%dT%H:%M:%E*SZ', '2018-10-12T13:22:27.120Z')