在 java/ Kotlin 中将日期字符串从“2020-05-08T11:01:48.3300000Z”日期时间字符串格式化为 m/d/yyyy 的正确方法是什么

What is the correct way to format a date string to m/d/yyyy from "2020-05-08T11:01:48.3300000Z" datetime string in java/ Kotlin

我正在尝试格式化从服务器接收到的 DateTime 字符串。我使用了以下格式并且 none 正在工作 - AppConstants.API_DATE_TIME_FORMAT =

 - `"yyyy-MM-dd'T'HH:mm:ss.SSS'Z'"`
 - `"yyyy-MM-dd'T'HH:mm:ss.SSSZ'Z'"`
 - `"yyyy-MM-dd'T'HH:mm:ss.SSSZ"`
 - `"yyyy-MM-dd'T'HH:mm:ss.SSSXX'Z'"`
 - `"yyyy-MM-dd'T'hh:mm:ss.SSSSSS'Z'"`

 and - 

     fun getFormattedDate(apiFormatDateTime: String): String {
        return try{
            val parser = SimpleDateFormat(AppConstants.API_DATE_TIME_FORMAT, Locale.getDefault())
            val formatter = SimpleDateFormat(AppConstants.UI_DATE_FORMAT, Locale.getDefault())
            val date = parser.parse(apiFormatDateTime)!!
            formatter.format(date)
        }catch (ex : Exception){
            apiFormatDateTime
        }
    }

这个有效

        String d="2020-05-08T11:01:48.3300000Z";
        DateFormat originalFormat = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSSSSSS'Z'");
        DateFormat targetFormat = new SimpleDateFormat("yyyyMMdd");
        Date date = originalFormat.parse(d);
        String formattedDate = targetFormat.format(date); 
        System.out.println("date==>"+formattedDate);

输出::

date==>20200508

您可以尝试使用 LocalDateTime 和 DateTimeFormatter

String str = "1986-04-08 12:30";
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm");
LocalDateTime dateTime = LocalDateTime.parse(str, formatter);
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm");
LocalDateTime dateTime = LocalDateTime.of(1986, Month.APRIL, 8, 12, 30);
String formattedDateTime = dateTime.format(formatter); // "1986-04-08 12:30"

归功于:

您可以像下面这样尝试

try {
            XMLGregorianCalendar dt = DatatypeFactory.newInstance().newXMLGregorianCalendar("2020-05-13T12:12:12.123456Z");
            String dateValue = new SimpleDateFormat("MM/dd/yyyy").format(dt.toGregorianCalendar().getTime());
            System.out.println("datevalue="+dateValue);
        } catch (DatatypeConfigurationException e) {
            e.printStackTrace();
        }   

输出:datevalue=05/13/2020

这是我从 UTC 格式获取日期和时间的方法 -

    const val API_DATE_TIME_FORMAT = "yyyy-MM-dd'T'HH:mm:ss.SSSSSSS'Z'"
    const val UI_DATE_FORMAT = "MM/dd/yyyy"
    const val UI_TIME_FORMAT = "hh:mm:ss a"

/**
     * Function for getting date from api datetime string
     * @return formatted time
     */
    fun getFormattedDate(apiFormatDateTime: String): String {
        return try{
            val parser = SimpleDateFormat(AppConstants.API_DATE_TIME_FORMAT, Locale.getDefault())
            parser.timeZone = TimeZone.getTimeZone("UTC")
            val formatter = SimpleDateFormat(AppConstants.UI_DATE_FORMAT, Locale.getDefault())
            val date = parser.parse(apiFormatDateTime)!!
            formatter.timeZone = TimeZone.getDefault()
            formatter.format(date)
        }catch (ex : Exception){
            apiFormatDateTime
        }
    }

    /**
     * Function for getting time from api datetime string
     * @return formatted time
     */
    fun getFormattedTime(apiFormatDateTime: String): String {
        return try{
            val parser = SimpleDateFormat(AppConstants.API_DATE_TIME_FORMAT, Locale.getDefault())
            parser.timeZone = TimeZone.getTimeZone("UTC")
            val formatter = SimpleDateFormat(AppConstants.UI_TIME_FORMAT, Locale.getDefault())
            formatter.timeZone = TimeZone.getDefault()
            formatter.format(parser.parse(apiFormatDateTime)!!)
        }catch (ex : Exception){
            apiFormatDateTime
        }
    }

java.time

我建议您使用 java.time,现代 Java 日期和时间 API,作为您的日期和时间工作。在Java(因为这是我能写的):

    ZoneId zone = ZoneId.of("Asia/Kolkata");
    DateTimeFormatter uiDateFormatter = DateTimeFormatter.ofPattern("M/d/uuuu");

    String isoF8601ormatDateTime = "2020-05-08T11:01:48.3300000Z";
    Instant time = Instant.parse(isoF8601ormatDateTime);
    String uiString = time.atZone(zone)
            .format(uiDateFormatter);

    System.out.println(uiString);

输出为:

5/8/2020

注意事项:

  • 您的 API 的格式是 ISO 8601。java.time 的 类 将最常见的 ISO 8601 变体解析为默认格式,也就是说,我们不需要指定任何格式化程序.
  • 我的代码还在格式化之前将日期转换为用户的时区。大多数用户都会期望这一点。请把你用户的时区放在我放的地方 Asia/Kolkata.

额外信息:格式化时间,也在用户的时区:

    DateTimeFormatter uiTimeFormatter
            = DateTimeFormatter.ofPattern("hh:mm:ss a", Locale.ENGLISH);
    String uiTimeString = time.atZone(zone).format(uiTimeFormatter);
    System.out.println(uiTimeString);

04:31:48 PM

您的尝试出了什么问题?

  • SimpleDateFormat 无法正确解析秒的 7 位小数。它只支持毫秒,正好是三位小数。 SimpleDateFormat 需要 3300000 毫秒,即 3300 秒或将近一个小时,它会添加到解析时间中。
  • 传入字符串中的
  • Z 是 UTC 偏移量(零),需要这样解析,否则您将得到不正确的结果。
  • Z 不带引号将解析像 +0000 这样的偏移量,但不会解析 ZXX 将解析 Z,但该尝试失败了,因为您在 Z.
  • 之后还需要(一个)Z
  • 您在格式化前没有转换为用户的时区。

链接