【问题标题】:How to format date with T parameter in between in java?如何在java中使用T参数格式化日期?
【发布时间】:2020-09-05 22:01:55
【问题描述】:

我有一个这种格式的日期 - 01 May 2020,我想以以下格式解析它 - 2020-05-01T00:00:00。我正在使用以下代码 -

static String convertDateStringFormat(String dateString, String originalDateFormat, String outputDateFormat){
        DateFormat inputFormat = new SimpleDateFormat(originalDateFormat, Locale.ENGLISH);
        Date input = null;
        try {
            input = inputFormat.parse(dateString);
        } catch (ParseException e) {
            e.printStackTrace();
        }
        DateFormat outputFormat = new SimpleDateFormat(outputDateFormat, Locale.ENGLISH);
        return outputFormat.format(input);
    }

我将参数传递为 - convertDateStringFormat("01 May 2020", "dd MMM yyyy", "yyyy-MM-dd'T'HH:mm:ss")。我不知道我做错了什么,但它给了我这个异常 - java.lang.IllegalArgumentException: Parse error: 2020-05-01T00:00:00,所以看起来它正在转换为正确的格式然后抛出异常?

【问题讨论】:

  • 无法复制。发布的代码返回带有发布参数的2020-05-01T00:00:00。您确定这是引发该异常的代码吗?此外,您应该使用ThreeTenABP重写此代码。
  • 是的,这是我在项目中使用的确切代码。我正在做的另一件事是将从此方法返回的字符串值放入 java.util.Date 构造函数
  • 那行不通。日期不采用这样的格式化字符串。您发布的代码工作正常。
  • inputFormat.parse(dateString); 返回一个Date 对象。
  • 即使在 Android 上,甚至在较旧的 Android 版本上,也请考虑丢弃长期过时且臭名昭著的麻烦 SimpleDateFormat 和朋友,并将 ThreeTenABP 添加到您的 Android 项目中以使用 java.time,现代 Java 日期和时间 API。使用起来感觉好多了。

标签: android date datetime java-8 datetime-format


【解决方案1】:

使用DateTimeFormatterBuilder 构建格式,hour 默认为0,然后将日期字符串解析为LocalDateTime

演示:

import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.time.format.DateTimeFormatterBuilder;
import java.time.temporal.ChronoField;

public class Main {
    public static void main(String[] args) {
        DateTimeFormatter format = new DateTimeFormatterBuilder()
                                    .append(DateTimeFormatter.ofPattern("dd MMM yyyy"))
                                    .parseDefaulting(ChronoField.HOUR_OF_DAY, 0)
                                    .toFormatter();

        String strDate = "01 May 2020";
        LocalDateTime date = LocalDateTime.parse(strDate, format);

        DateTimeFormatter targetFormat = DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:mm:ss");
        String strDateInTargetFormat = date.format(targetFormat);

        System.out.println(strDateInTargetFormat);
    }
}

输出:

2020-05-01T00:00:00

【讨论】:

    【解决方案2】:

    这样可以将一种格式转换为另一种格式:

    DateFormat originalFormat = new SimpleDateFormat("dd MMM yyyy", Locale.ENGLISH);
    DateFormat targetFormat = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss");
    Date date = originalFormat.parse("01 May 2020");
    String formattedDate = targetFormat.format(date); 
    
    

    【讨论】:

    • 不要使用过时的日期/时间 API。检查this以了解更多信息。
    • 不会过时吧?显然,对此有不止一种意见。自 2014 年以来,Oracle 的官方建议是使用 java.time,而不是 DateDateFormatSimpleDateFormat。我认为旧类的设计令人困惑,而且——是的——已经过时了。
    • 承认,如果你的 Android minSDK 低于 26,你需要权衡现代 API 的优势和外部依赖的成本,它不是免费的。在这种情况下,它将依赖于已经是 Java 8、9、10、11、12、13、14、15 的一部分的代码的反向移植……我认为我们可以认为它坚如磐石。
    • @ArvindKumarAvinash 这是一个非常有用的链接,谢谢。
    • @KrishnaSony 这些糟糕的日期时间类随着JSR 310 的采用而成为遗产。 Sun、Oracle、IBM 和 JCP 社区随后同意放弃那些旧课程。我建议你也这样做。
    【解决方案3】:

    tl;博士

    LocalDate
    .parse( 
        "01 May 2020" , 
        DateTimeFormatter
        .ofPattern( "dd MMMM uuuu" )
        .withLocale( Locale.US ) 
    )
    .atStartOfDay(
        ZoneId.of( "Africa/Tunis" )
    )
    .format(
        DateTimeFormatter.ISO_LOCAL_DATE_TIME
    )
    

    看到这个code run live at IdeOne.com

    2020-05-01T00:00:00

    详情

    你说:

    我有一个这种格式的日期 - 2020 年 5 月 1 日

    这意味着你有文本,String不是日期。日期时间对象没有“格式”。

    将您的文本解析为LocalDate

    String input = "01 May 2020" ;
    DateTimeFormatter f = DateTimeFormatter.ofPattern( "dd MMMM uuuu" ).withLocale( Locale.US ) ;
    LocalDate ld = LocalDate.parse( input , f ) ;
    

    你说:

    想要以以下格式解析它 - 2020-05-01T00:00:00。

    不,那不是解析。那就是生成文本

    但首先我们需要确定一天中的时间。我想你想要一天的第一刻。

    某些时区的某些日期并非从 00:00 开始。所以总是让 java.time 决定一天中的第一个时刻。我们将这一刻记录为ZonedDateTime 对象。

    ZoneId z = ZoneId.of( "Asia/Amman" ) ;
    ZonedDateTime zdt = ld.atStartOfDay( z ) ;
    

    您要求以不指明时区或与 UTC 偏移的格式生成文本。我不建议这样做,因为对此类文本的阅读是模棱两可的。但如果您坚持,java.time 包含一个预定义的format for the kind of text you desire。这种格式属于ISO 8601 中定义的格式。

    String output = zdt.format( DateTimeFormatter.ISO_LOCAL_DATE_TIME ) ;
    

    看到这个code run live at IdeOne.com

    输出:2020-05-01T00:00:00


    关于java.time

    java.time 框架内置于 Java 8 及更高版本中。这些类取代了麻烦的旧 legacy 日期时间类,例如 java.util.DateCalendarSimpleDateFormat

    要了解更多信息,请参阅Oracle Tutorial。并在 Stack Overflow 上搜索许多示例和解释。规格为JSR 310

    Joda-Time 项目现在位于maintenance mode,建议迁移到java.time 类。

    您可以直接与您的数据库交换 java.time 对象。使用符合JDBC 4.2 或更高版本的JDBC driver。不需要字符串,不需要java.sql.* 类。 Hibernate 5 和 JPA 2.2 支持 java.time

    从哪里获得 java.time 类?

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-08-31
      • 2014-01-19
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多