我有一个字符串日期格式01/01/2017 6:54 PM并想将其转换为2017-01-01T00:00:05.383 + 0100在Scala中的ISOFormat

时间:2017-08-28 07:43:45

标签: scala jodatime datetime-format datetime-parsing

   def cleantz( time : String ) : String = {
    var sign_builder= new StringBuilder ++= time
    println(sign_builder)
    var clean_sign = ""
    if (sign_builder.charAt(23).toString == "-"){
      clean_sign= sign_builder.replace(23,24,"-").toString()
    }else{
      clean_sign = sign_builder.replace(23,24,"+").toString()
    }
    var time_builder= new StringBuilder ++= clean_sign
    if (time_builder.charAt(26).toString == ":"){
      val cleanz = time_builder.deleteCharAt(26)
      cleanz.toString()
    }else{
      time_builder.toString()
    }
  }

    val start = ISO8601Format.parse(cleantz(01/01/2017 6:54 PM))

我收到此错误:

  

java.lang.StringIndexOutOfBoundsException:字符串索引超出范围:23

3 个答案:

答案 0 :(得分:2)

java.time

为了完整起见,我想提供现代答案。这很简单直接。

很抱歉,我既不能编写Scala代码也不能在我的计算机上测试它。我必须相信你能从Java翻译。

private static DateTimeFormatter inputFormatter 
        = DateTimeFormatter.ofPattern("MM/dd/yyyy h:mm a", Locale.US);

public static String cleantz(String time) {
    return LocalDateTime.parse(time, inputFormatter)
            .atOffset(ZoneOffset.ofHours(1))
            .toString();
}

现在cleantz("01/01/2017 6:54 PM")返回{8}格式的2017-01-01T18:54+01:00。我会立即假设你已经定了。如果由于某种原因您也想要或需要秒数,请将.toString();替换为:

            .format(DateTimeFormatter.ISO_OFFSET_DATE_TIME);

现在结果为2017-01-01T18:54:00+01:00。在这两种情况下,如果存在毫秒,则会打印毫秒。

由于AMPM几乎不会用于其他语言而非英语,我建议您为DateTimeFormatter.ofPattern()提供一个说英语的语言环境(在我的示例中,我使用了Locale.US )。如果未能提供区域设置,则会导致许多计算机上的代码在非英语语言设置下失败。

为什么java.time

  • SimpleDateFormat和朋友们已经过时了,而且非常麻烦。我无法计算Stack Overflow上提出的问题,因为SimpleDateFormat表现得与每个理智程序员所期望的不同,或者没有帮助调试我们不时做出的简单错误。
  • Joda-Time很长一段时间都很好。今天Joda-Time homepage说:

      

    请注意,Joda-Time被认为是一个很大程度上“完成”的项目。   没有计划重大改进。如果使用Java SE 8,请迁移   到java.time(JSR-310)。

  • java.time是现代Java日期&时间API使用Joda-Time和同一首席开发人员Stephen Colebourne的经验构建。它内置于Java 8及更高版本中,并且Java 6和7存在一个backport,因此您也可以使用相同的类。

答案 1 :(得分:1)

假设您的输入字符串为01/01/2017 6:54 PM:它有18个字符。当你调用charAt(23)时,它会尝试获取位置23的字符,该字符不存在:字符串的位置从零(第一个0)到17({{1} })。如果您尝试获得大于该位置的位置,则会抛出M

但是你不需要做所有这些字符串操作。如果您的字符串以某种格式表示日期,并希望将其转换为其他格式,那么您只需要:

  1. 将原始字符串解析为日期
  2. 将此日期格式化为其他格式
  3. 所以你需要2个不同的Joda格式化程序(每个步骤一个)。但还有一个细节。

    输入有一个日期(StringIndexOutOfBoundsException)和一个时间(01/01/2017),输出有一个日期(6:54 PM),一个时间(2017-01-01)和UTC offset18:54:00.000)。所以你还有一个额外的步骤:

    1. 将原始字符串解析为日期
    2. +0100偏移量添加到已解析日期
    3. 将此日期格式化为其他格式
    4. 使用Joda-Time,可以使用以下代码实现:

      +0100

      输出将是:

        

      2017-01-01T18:54:00.000 + 01:00

      请注意,偏移量打印为import org.joda.time.DateTimeZone import org.joda.time.LocalDateTime import org.joda.time.format.DateTimeFormat import org.joda.time.format.ISODateTimeFormat val fmt = DateTimeFormat.forPattern("dd/MM/yyyy h:mm a") // parse the date val localDate = LocalDateTime.parse("01/01/2017 6:54 PM", fmt) // add the +01:00 offset val dt = localDate.toDateTime(DateTimeZone.forOffsetHours(1)) // format to ISO8601 print(ISODateTimeFormat.dateTime().print(dt)) 。如果您想要+01:00(没有+0100),则需要创建另一个格式化程序:

      :

      输出将是:

        

      2017-01-01T18:54:00.000 + 0100

答案 2 :(得分:1)

这是我用来获得相同结果的代码。发生错误是因为我试图解析错误的日期格式。

   val inputForm = new SimpleDateFormat("MM/dd/yyyy h:mm a")
   val outputForm = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSSZ")

   val dateFormat1 = start_iso
   val dateFormat2 = stop_iso

   val start = outputForm.format(inputForm.parse(start_iso))
 val stop = outputForm.format(inputForm.parse(stop_iso))

   println(start)
println(stop)