检查字符串日期中是否有时间,并在Android中做一些事情



我有一个方法来格式化我的特定数据字符串

public static String dateFormatter(String dateToFormat){
SimpleDateFormat dateParser = new SimpleDateFormat("yyyy-MM-dd", Locale.UK);

// All the fields in dateFormatter must be in dateParser
SimpleDateFormat dateFormatter = new SimpleDateFormat("yyyy, MMM d, EEE", Locale.UK);
Date date = new Date();
try {
date = dateParser.parse(dateToFormat);
} catch (ParseException e) {
e.printStackTrace();
}
assert date != null;

return dateFormatter.format(date);
}

我遇到的问题是字符串日期解析为dateToFormat可以在以下日期格式模式

  1. 2021-03-02将使用"yyyy-MM-dd"在dateParser
  2. 2021-03-02 20:16将使用"yyyy-MM-dd HH:mm"在dateParser
  3. 2021-03-02 20:16:28将使用日期格式模式"yyyy-MM-dd HH:mm:ss"在dateParser

我希望datesparser被分配一个if语句,而不是我回到代码每次更改,以便datesparser根据所解析的日期使用特定的格式,例如

SimpleDateFormat dateParser;
if ("yyyy-MM-dd"){
dateParser = new SimpleDateFormat("yyyy-MM-dd", Locale.UK);
}else if ("yyyy-MM-dd HH:mm") {
dateParser = new SimpleDateFormat("yyyy-MM-dd HH:mm", Locale.UK);
}else if ("yyyy-MM-dd HH:mm:ss") {
dateParser = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss", Locale.UK);
}

,"yyyy-MM-dd"yyyy-MM-dd HH:mm"是已解析字符串dateToFormat

的格式模式。

分别为yyyy-MM-dd、yyyy-MM-dd HH:mm、yyyy-MM-dd HH:mm:ss创建3个不同的格式化器formatter1、formatter2、formatter3

private String dateFormatter(String dateToFormat) {
Date date = null;
SimpleDateFormat formatter1=new SimpleDateFormat("yyyy-MM-dd", Locale.UK);
SimpleDateFormat formatter2=new SimpleDateFormat("yyyy-MM-dd HH:mm", Locale.UK);
SimpleDateFormat formatter3=new SimpleDateFormat("yyyy-MM-dd HH:mm:ss", Locale.UK);
try {
try {
date = formatter1.parse(dateToFormat);
} catch (
Exception exp) {
try {
date = formatter2.parse(dateToFormat);
} catch (Exception exp2) {
try {
date = formatter3.parse(dateToFormat);
} catch (ParseException e) {
e.printStackTrace();
}
}
}
SimpleDateFormat dateFormatter = new SimpleDateFormat("yyyy, MMM d, EEE", Locale.UK);
return dateFormatter.format(date);
} catch (Exception e) {
e.printStackTrace();
}
return null;
}

java。格式模式

的时间和可选部分考虑使用java。time,现代Java日期和时间API,用于您的日期工作。下面的方法可以做到这一点。因为java。如果没有必要为每个调用重新创建格式化器,我就把它们放在方法之外。

private static final DateTimeFormatter inputParser
= DateTimeFormatter.ofPattern("uuuu-MM-dd[ HH:mm[:ss]]");
private static final DateTimeFormatter outputFormatter 
= DateTimeFormatter.ofPattern("uuuu, MMM d, EEE", Locale.UK);
public static String dateFormatter(String dateToFormat){
LocalDate date = LocalDate.parse(dateToFormat, inputParser);
return date.format(outputFormatter);
}

Try it out:

System.out.println("2021-03-02          -> " + dateFormatter("2021-03-02"));
System.out.println("2021-03-02 20:16    -> " + dateFormatter("2021-03-02 20:16"));
System.out.println("2021-03-02 20:16:28 -> " + dateFormatter("2021-03-02 20:16:28"));

输出是:

2021-03-02          -> 2021, Mar 2, Tue
2021-03-02 20:16    -> 2021, Mar 2, Tue
2021-03-02 20:16:28 -> 2021, Mar 2, Tue

输入解析器格式模式字符串中的方括号表示可选部分。所以一天中的时间是允许存在或不存在的。如果它在那里,秒可以存在或不存在。

这就是说,你不应该在应用程序中将日期和时间作为字符串处理。处理LocalDate,或者如果有任何可能你需要一天中的时间,那么例如ZonedDateTime。当您获得字符串输入时,首先解析它。只有当你必须给出字符串输出时,才格式化回字符串。

带有if语句

你能找到一种方法,我可以使用SimpleDateFormat

我不想那样做。SimpleDateFormat级是一个臭名昭著的麻烦制造者,幸运的是早就过时了

是否有一种方法,我只能使用if语句,这样我就不能使用许多simpledateformat

它不会让你更少的格式化器,但你可以使用if语句。按字符串的长度选择;

public static String dateFormatter(String dateToFormat){
LocalDate date;
if (dateToFormat.length() == 10) { // uuuu-MM-dd
date = LocalDate.parse(dateToFormat, dateParser);
} else if (dateToFormat.length() == 16) { // uuuu-MM-dd HH:mm
date = LocalDate.parse(dateToFormat, dateTimeNoSecsParser);
} else if (dateToFormat.length() == 19) { // uuuu-MM-dd HH:mm:ss
date = LocalDate.parse(dateToFormat, dateTimeWithSecsParser);
} else {
throw new IllegalArgumentException("Unsupported length " + dateToFormat.length());
}
return date.format(outputFormatter);
}
现在我们只需要声明四个格式化器,三个用于解析,一个用于格式化。我把构造解析器留给你自己。

我猜相同的if-else结构也将与SimpleDateFormat一起工作。您甚至可以只从输入字符串的长度中选择格式模式字符串,并且在每次调用该方法时只构造一个SimpleDateFormat实例。我重复一遍:我自己不会使用SimpleDateformat

问题:不java。何时需要Android API级别26?

调用需要API级别26(当前最小值为16):java.time.format.DateTimeFormatter # ofPattern

编辑:与您从这个错误信息中可能想到的相反。time在新旧Android设备上都能很好地运行。它只需要至少Java 6.

  • 在Java 8和更高版本以及较新的Android设备(从API级别26开始),现代API是内置的。
  • 在非android Java 6和7中获得ThreeTen Backport,现代类的后端口(JSR 310的ThreeTen;参见底部的链接)。
  • 在旧的Android上使用desugaring或Android版的ThreeTen Backport。它被称为ThreeTenABP。在后一种情况下,请确保从org.threeten.bp和子包中导入日期和时间类。

链接
  • Oracle教程:日期时间说明如何使用java.time.
  • Java规范请求(JSR) 310,其中首次描述了java.time
  • ThreeTen Backport项目,java.time到Java 6和7的Backport (ThreeTen for JSR-310)。
  • Java 8+ api
  • ThreeTenABP, Android版的ThreeTen Backport
  • 问题:如何在Android项目中使用ThreeTenABP,有一个非常彻底的解释。

相关内容