下面显示的函数返回日期,例如“2010年9月8日星期六00:00”。但我希望以“yyyy-MM-dd HH:mm”的格式获得日期。这段代码有什么问题?
String date = "2010-08-25";
String time = "00:00";
同样在一台笔记本电脑中输出,例如23:45是11:45。如何准确定义24格式?
private static Date date(final String date,final String time) {
final Calendar calendar = Calendar.getInstance();
String[] ymd = date.split("-");
int year = Integer.parseInt(ymd[0]);
int month = Integer.parseInt(ymd[1]);
int day = Integer.parseInt(ymd[2]);
String[] hm = time.split(":");
int hour = Integer.parseInt(hm[0]);
int minute = Integer.parseInt(hm[1]);
calendar.set(Calendar.YEAR,year);
calendar.set(Calendar.MONTH,month);
calendar.set(Calendar.DAY_OF_MONTH,day);
calendar.set(Calendar.HOUR,hour);
calendar.set(Calendar.MINUTE,minute);
SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm");
Date d = calendar.getTime();
String dateString= dateFormat.format(d);
Date result = null;
try {
result = (Date)dateFormat.parse(dateString);
} catch (ParseException e) {
e.printStackTrace();
}
return result;
}
答案 0 :(得分:3)
此代码有什么问题?
您似乎期望返回的Date
对象知道您解析它的格式 - 它没有。这只是一个瞬间。如果您想要特定格式的日期,请使用SimpleDateFormat.format
,就这么简单。 (好吧,或者你使用更好的库,例如Joda Time。)
将Date
值视为int
- int
只是一个数字;你没有“十六进制中的int”或“十进制中的int”......当你想要格式化它时,你做出了这个决定。 Date
也是如此。
(同样,Date
与特定日历,时区或区域设置无关。这只是一个瞬间。)
答案 1 :(得分:2)
答案 2 :(得分:2)
你是如何打印出来的?如果您只是使用System.out.println(date("2010-08-25", "00:00")
,则可能会获得Sat Sep 8 00:00 PDT 2010
,具体取决于您正在运行的计算机中的当前日期时间格式设置。但你能做的就是:
Date d = date("2010-08-25", "00:00");
System.out.println(new SimpleDateFormat("yyyy-MM-dd HH:mm").format(d));
只是好奇为什么你要为整个过程烦恼,因为你可以通过连接你的初始日期和时间字符串来简单地得到结果。
答案 3 :(得分:2)
Date-Time
对象。下面显示的函数返回日期,例如“太平洋夏令时间 9 月 8 日星期六 00:00 2010"。但我希望得到以下格式的日期 “yyyy-MM-dd HH:mm”。
标准日期时间类没有任何属性来保存格式信息。即使某些库或自定义类承诺这样做,它也违反了 Single Responsibility Principle。 Date-Time 对象应该存储有关日期、时间、时区等的信息,与格式无关。以所需格式表示日期时间对象的唯一方法是使用日期时间解析/格式化类型将其格式化为 String
:
java.time.format.DateTimeFormatter
java.text.SimpleDateFormat
java.util.Date
:java.util.Date
对象仅表示自称为“纪元”的标准基准时间(即 1970 年 1 月 1 日 00 日)以来的 毫秒 数: 00:00 GMT(或UTC)。由于它不保存任何时区信息,它的 toString
函数应用 JVM 的时区返回一个 String
格式,EEE MMM dd HH:mm:ss zzz yyyy
,从这个 毫秒值。要以不同的格式和时区获取 String
对象的 java.util.Date
表示,您需要将 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
java.time
API。java.util
日期时间 API 及其格式化 API SimpleDateFormat
已过时且容易出错。建议完全停止使用它们并切换到 modern Date-Time API*。
使用 java.time
(现代日期时间 API)的解决方案:
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
您一定注意到我没有使用 DateTimeFormatter
来解析 String date
和 String time
。这是因为您的日期和时间字符串符合 ISO 8601 标准。现代日期时间 API 基于 ISO 8601,只要日期时间字符串符合 ISO 8601 标准,就不需要明确使用 DateTimeFormatter
对象。
从 Trail: Date Time 了解有关现代 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。
答案 4 :(得分:0)
我很惊讶您在不同的计算机上获得了不同的日期输出。理论上,SimpleDateFormat模式“H”应该以24h格式输出日期。你是晚上11点45分还是上午11点45分?
虽然它不应该影响结果,但SimpleDateFormat和Calendar依赖于Locale,因此您可以尝试指定要使用的确切语言环境(Locale.US),看看是否有任何区别。
作为最终建议,如果您愿意,您也可以尝试使用Joda-Time库(DateTime)代替日期操作。它使得使用日期对象变得更加容易。
DateTime date = new DateTime( 1991, 10, 13, 23, 39, 0);
String dateString = new SimpleDateFormat("yyyy-MM-dd HH:mm").format( date.toDate());
DateTime newDate = DateTime.parse( dateString, DateTimeFormat.forPattern("yyyy-MM-dd HH:mm"));