我将Date从String类型Date转换为Date类型Date,使用SimpleDateFormat但是 我得到的结果日期正在改变。任何人都告诉我为什么会改变 同样我应该使用什么来从字符串获取正确的日期类型日期,而不是我在这里获得的更改日期类型日期。
Date d = null;
String startTime="2012-03-17 16:00:00 PM";
DateFormat sdf = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss a");
try {
d= sdf.parse(startTime);
} catch (ParseException e) {}
System.out.println("DD="+d) //printing Sun Mar 18 04:00:00 IST 2012 ? why this
//Date enterd was 17 Mar 2012
答案 0 :(得分:2)
如果您将24小时时钟和AM / PM标记结合使用,那就很不方便了。在您的情况下,您应该使用“HH”(大写字母H)来解析0-23范围内的小时字段并忽略AM / PM后缀或使用具有适当AM / PM后缀的12小时时钟(在您的情况下为“04”) :00:00 PM“)。
答案 1 :(得分:2)
AM/PM 标记不适用于 24 小时制时间格式。它应该是 2012-03-17 04:00:00 PM
或 2012-03-17 16:00:00
。
java.util
日期时间 API 及其格式化 API SimpleDateFormat
已过时且容易出错。建议完全停止使用它们并切换到 modern Date-Time API*。
另外,下面引用的是来自 home page of Joda-Time 的通知:
<块引用>请注意,从 Java SE 8 开始,要求用户迁移到 java.time (JSR-310) - JDK 的核心部分,取代了该项目。
使用 java.time
(现代日期时间 API)的解决方案:
让我们首先尝试按照您的方式进行操作:
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.Locale;
public class Main {
public static void main(String[] args) {
String startDateTime = "2012-03-17 16:00:00 PM";
DateTimeFormatter dtf = DateTimeFormatter.ofPattern("uuuu-MM-dd hh:mm:ss a", Locale.ENGLISH);
LocalDateTime ldt = LocalDateTime.parse(startDateTime, dtf);
System.out.println(ldt);
}
}
输出:
<块引用>线程“main”中的异常java.time.format.DateTimeParseException: 无法解析文本“2012-03-17 16:00:00 PM”:无效值 ClockHourOfAmPm(有效值 1 - 12):16
如您所见,java.time
API 会正确抛出异常,通知您有关问题。另一方面,SimpleDateFormat
会错误地解析输入字符串。
现在,让我们看看如何正确解析它。为了正确解析它,我们将使用:
uuuu-MM-dd HH:mm:ss
,其中 H
指定 24 小时格式。对于日期时间字符串,您可以使用 y
而不是 u
而是 I prefer u
to y
。DateTimeFormatter#parse(CharSequence, ParsePosition)
,其中 ParsePosition
索引设置为 0
。演示:
import java.text.ParsePosition;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.Locale;
public class Main {
public static void main(String[] args) {
String startDateTime = "2012-03-17 16:00:00 PM";
DateTimeFormatter dtf = DateTimeFormatter.ofPattern("uuuu-MM-dd HH:mm:ss", Locale.ENGLISH);
ParsePosition pp = new ParsePosition(0);
LocalDateTime ldt = LocalDateTime.from(dtf.parse(startDateTime, pp));
System.out.println(ldt);
}
}
输出:
2012-03-17T16:00
注意: Never use SimpleDateFormat or DateTimeFormatter without a Locale。
从 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。
答案 2 :(得分:1)
16:00:00 PM
不是有效时间,SimpleDateFormat
会将其转换为第二天凌晨4:00。
答案 3 :(得分:1)
您在格式字符串中使用hh
,这是一种12小时格式。这是有道理的,因为你有一个AM / PM指示符(a
)......但 对16的值有意义。
我怀疑“下午16点”正在翻译到第二天凌晨4点,因此出现问题。 (奇怪的是,使用setLenient(false)
不会选择此错误。)
要么使用"yyyy-MM-dd HH:mm:ss"
格式并确保最后没有“PM”,或使用现有格式但是给它明智的价值观(04代替16)。
另外,我建议:
ParseException
。空抓块是一个非常糟糕的主意。Date.toString()
时,您无法更改输出格式。对于快速诊断而言,有时候也没关系,但它会给人一种误导性的印象,即Date
实际上有时区信息,而不是。{/ li>