如何根据Spark中的GMT lanuchTime获取活动任务的runTime?

问题描述 投票:0回答:1

我想获得一个活动任务的运行时。在/applications/[app-id]/stages/[stage-id]的REST API页面中,我可以详细获取任务信息。

enter image description here

你可以看到,当任务没有完成时,executorRunTime为0。我想我可以根据launchTime得到runTime。假设launchTime是2017-12-21T03:15:31.106GMT。我使用以下代码来计算runTime。

val format = new SimpleDateFormat("yyyy-MM-dd'T'hh:mm:ss'.'sss'GMT'", Locale.ENGLISH)
format.setTimeZone(TimeZone.getTimeZone("GMT"))
val launchTime = format.parse("2017-12-21T03:15:31.106GMT").getTime
val runTime = Calendar.getInstance(TimeZone.getTimeZone("GMT")).getTimeInMillis - 
              launchTime

但我得到一个负数。时间格式错了吗?或者是什么?

apache-spark simpledateformat gmt datetime-parsing
1个回答
0
投票

TL; DR

    String launchTimeString = "2017-12-21T03:15:31.106GMT";
    launchTimeString = launchTimeString.replaceFirst("GMT$", "Z");
    long launchTime = Instant.parse(launchTimeString).toEpochMilli();
    long runTime = System.currentTimeMillis() - launchTime;

(对不起,我只能写Java 8代码,我必须相信你能翻译。)

java.time和ISO 8601

Java 1.0和1.1中的日期和时间类已经过时了,而SimpleDateFormat尤其出了名的麻烦。我建议您停止使用它们并使用java.time,现代Java日期和时间API。与它合作真是太好了。

你的发布时间字符串有点搞笑。它类似于ISO 8601标准格式,在日期和时间之间具有特征T,但最终具有非标准GMT,其中遵循标准的字符串通常具有Z(或者与UTC的正或负偏移)。由于现代日期和时间类将ISO 8601解析为默认值,即没有任何明确的格式化程序,并且因为编写格式模式字符串似乎是一个无穷无尽的错误来源(当然不仅仅是你),我发现它很诱人修改您的字符串以符合标准,然后解析它。

格式模式出了什么问题?

格式化模式字符串有两个错误:

  • 你想要一天中的大写HH。小写hh是在AM或PM之间的小时,在1到12的间隔。对于SimpleDateFormat这个bug通常“只是”意味着12小时被理解为00(这将给你一个很长的运行时间)(现代) DateTimeFormatter更热切地告诉你,如果你对那个班级尝试相同的话,你会有一个错误)。
  • 虽然小写的ss在几秒钟内是正确的,但毫秒是大写的SSS。这肯定是你的打击:106你的字符串被认为是秒而不是毫秒,所以如果在03:16:46之前运行你的代码,你得到一个负的运行时间。

所以这两个错误归结为:格式模式字符串区分大小写,因此您需要注意正确的情况。

链接

© www.soinside.com 2019 - 2024. All rights reserved.