Java 如何处理卡夫卡流中的不同时区?

Java 如何处理卡夫卡流中的不同时区?,java,apache-kafka,apache-kafka-streams,Java,Apache Kafka,Apache Kafka Streams,因此,我评估了Kafka流以及它能做些什么,以确定它是否适合我的用例,因为我需要对传感器的数据进行每15分钟、每小时、每天的聚合,并且发现它的窗口功能非常有用。 因为我可以通过在KGroupedStream上应用windowedBy()来创建窗口,但问题是窗口是在UTC中创建的,我希望我的数据按其原始时区分组,而不是按UTC时区分组,因为这会妨碍聚合,所以任何人都可以在这方面帮助我。您可以“移动”使用自定义时间戳提取器的时间戳——在将结果写回输出主题之前,可以使用转换器,并通过context.f

因此,我评估了Kafka流以及它能做些什么,以确定它是否适合我的用例,因为我需要对传感器的数据进行每15分钟、每小时、每天的聚合,并且发现它的窗口功能非常有用。 因为我可以通过在
KGroupedStream
上应用
windowedBy()
来创建窗口,但问题是窗口是在UTC中创建的,我希望我的数据按其原始时区分组,而不是按UTC时区分组,因为这会妨碍聚合,所以任何人都可以在这方面帮助我。

您可以“移动”使用自定义
时间戳提取器的时间戳
——在将结果写回输出主题之前,可以使用
转换器
,并通过
context.forward(key、value、To.all().withTimestamps())将时间戳“移位”回去


功能请求票证:

因此,为了解决这个问题,我创建了自定义
时间戳提取器
,并使用它更改流窗口创建时间,以记录有效负载的时间,如下所示

public class RecordTimeStampExtractor implements TimestampExtractor {

    @Override
    public long extract(ConsumerRecord<Object, Object> record, long previousTimestamp) {
        JsonObject data = (JsonObject) new JsonParser().parse(record.value().toString());
        Timestamp recordTimestamp = Timestamp.valueOf(data.get(Constant.SLOT).getAsString());
        return recordTimestamp.getTime();
    }

}
公共类RecordTimeStampExtractor实现TimestampExtractor{
@凌驾
公共长提取(消费者记录记录,长前时间戳){
JsonObject数据=(JsonObject)新建JsonParser().parse(record.value().toString());
Timestamp recordTimestamp=Timestamp.valueOf(data.get(Constant.SLOT).getAsString());
返回recordTimestamp.getTime();
}
}

所以现在我已经用我的本地时区测试了它,昨天是IST 05:30,它工作正常,而且卡夫卡流正在基于记录时间戳创建窗口。也将使用其他时区进行测试并更新答案

时间是按unix历元时间分组的,因此无论您需要做什么分析,为什么不能改变这些时间?您需要更详细地思考时区的性质。例如,在美国太平洋时区,标准时间与UTC的偏差为-8小时,夏令时与UTC的偏差为-7小时。因此,“一天”在春季过渡日为25小时,秋季过渡日为23小时。如果您需要为世界上的每个时区保留单独的分组,您的数据肯定会膨胀到非常大的比例。再说一次,也许这样的细节对你来说并不重要?仔细想想。@cricket_007,因为我必须将这些结果保存回去,并在相应的时区中显示给用户。您应该保留unix纪元时间,然后让用户转换为自己的
LocalDateTime
(假设Java 8 API)是的,先生,虽然我没有使用
Transformer
,但我仍然可以看到预期的输出,所以我必须很好地使用
Transformer
。如果不将数据移回,时间戳将位于UTC时区。如果这不是问题,你就不需要把它们移回去。