标准库不支持格式化的Date-Time 对象。
下面显示的函数返回日期,例如“9 月 8 日星期六 00:00 PDT
2010”。但我希望得到以下格式的日期
"yyyy-MM-dd HH:mm"。
标准的日期时间类没有任何属性来保存格式信息。即使某些库或自定义类承诺这样做,它也打破了Single Responsibility Principle。 Date-Time 对象应该存储有关日期、时间、时区等的信息,而不是格式。以所需格式表示日期时间对象的唯一方法是使用日期时间解析/格式化类型将其格式化为 String:
-
对于现代日期时间 API:
java.time.format.DateTimeFormatter
-
对于旧的日期时间 API:
java.text.SimpleDateFormat
关于java.util.Date:
java.util.Date 对象仅表示自称为“纪元”的标准基准时间(即 1970 年 1 月 1 日 00:00)以来的毫秒数: 00 GMT(或 UTC)。由于它不保存任何时区信息,它的 toString 函数应用 JVM 的时区以返回格式为 EEE MMM dd HH:mm:ss zzz yyyy 的 String,从这个 毫秒 值。要以不同的格式和时区获取java.util.Date 对象的String 表示,您需要使用具有所需格式和适用时区的SimpleDateFormat,例如
Date date = new Date(); // In your case, it will be Date date = date("2010-08-25", "00:00");
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm", Locale.ENGLISH);
// sdf.setTimeZone(TimeZone.getTimeZone("America/New_York")); // For a timezone-specific value
String strDate = sdf.format(date);
System.out.println(strDate);
您的函数Date date(String, String) 容易出错。
您可以简单地将日期和时间字符串与分隔符组合,然后使用SimpleDateFormat 来解析组合字符串,例如您可以将它们与空白字符结合起来作为分隔符,以使用上面显示的相同 SimpleDateFormat。
private static Date date(final String date, final String time) throws ParseException {
return sdf.parse(date + " " + time);
}
请注意,使用分隔符不是强制性要求,例如您可以使用 sdf.parse(date + time) 进行操作,但为此,您需要将 sdf 的格式更改为 yyyy-MM-ddHH:mm,虽然正确,但可能看起来令人困惑。
演示:
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Locale;
public class Main {
static final SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm", Locale.ENGLISH);
public static void main(String[] args) throws ParseException {
Date date = date("2010-08-25", "00:00");
String strDate = sdf.format(date);
System.out.println(strDate);
}
private static Date date(final String date, final String time) throws ParseException {
return sdf.parse(date + " " + time);
}
}
输出:
2010-08-25 00:00
ONLINE DEMO
切换到java.time API。
java.util 日期时间 API 及其格式化 API SimpleDateFormat 已过时且容易出错。建议完全停止使用,改用modern Date-Time API*。
使用现代日期时间 API java.time 的解决方案:
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.time.format.DateTimeFormatter;
import java.util.Locale;
public class Main {
public static void main(String[] args) {
LocalDateTime ldt = localDateTime("2010-08-25", "00:00");
// Default format i.e. the value of ldt.toString()
System.out.println(ldt);
// Custom format
DateTimeFormatter dtf = DateTimeFormatter.ofPattern("uuuu-MM-dd HH:mm", Locale.ENGLISH);
String strDate = dtf.format(ldt);
System.out.println(strDate);
}
private static LocalDateTime localDateTime(final String date, final String time) {
return LocalDateTime.of(LocalDate.parse(date), LocalTime.parse(time));
}
}
输出:
2010-08-25T00:00
2010-08-25 00:00
ONLINE DEMO
您一定注意到了,我没有使用DateTimeFormatter 来解析String date 和String time。这是因为您的日期和时间字符串符合 ISO 8601 标准。现代日期时间 API 基于 ISO 8601,只要日期时间字符串符合 ISO 8601 标准,就不需要明确使用 DateTimeFormatter 对象。
从 Trail: Date Time 了解有关现代日期时间 API 的更多信息。
* 出于任何原因,如果您必须坚持使用 Java 6 或 Java 7,您可以使用 ThreeTen-Backport,它将大部分 java.time 功能向后移植到 Java 6 和 7 . 如果您正在为一个 Android 项目工作并且您的 Android API 级别仍然不符合 Java-8,请检查 Java 8+ APIs available through desugaring 和 How to use ThreeTenABP in Android Project。