英文:
Java SimpleDateFormat convert "04:50 PM" to "16:50"
问题
我有一个关于从12小时制am/pm格式转换为24小时制的问题。我尝试使用SimpleDateFormat,但遇到了一些问题。
如你所见,我打印出了5行原始时间和转换后的时间,但在以“PM”结尾的情况下失败了。请注意,有些输入是24小时制,而其他输入是12小时制am/pm格式。
以下是我为转换编写的代码:
static String standardizeTime(String inputTime) throws ParseException {
SimpleDateFormat[] testInputFormat = new SimpleDateFormat[2];
SimpleDateFormat returnFormat = new SimpleDateFormat("HH:mm");
testInputFormat[0] = new SimpleDateFormat("hh:mm aa");
testInputFormat[1] = new SimpleDateFormat("HH:mm");
testInputFormat[0].setLenient(false);
testInputFormat[1].setLenient(false);
Date time;
for (int i = 0; i < testInputFormat.length; i++) {
try {
time = testInputFormat[i].parse(inputTime);
return returnFormat.format(time);
} catch (ParseException e) {
continue;
}
}
return "";
}
我应该如何更改以解决这个问题?
英文:
I have a question about converting from 12-hour am/pm format to 24-hour format. I have tried using SimpleDateFormat but encountered some problems.
As you can see, I printed 5 lines of original and converted time, but failed for cases ending with "PM". Note that some inputs are of the 24-hour format and others have the 12-hour am/pm format.
Below is the code I write for the conversion:
static String standardizeTime(String inputTime) throws ParseException {
SimpleDateFormat[] testInputFormat = new SimpleDateFormat[2];
SimpleDateFormat returnFormat = new SimpleDateFormat("HH:mm");
testInputFormat[0] = new SimpleDateFormat("hh:mm aa");
testInputFormat[1] = new SimpleDateFormat("HH:mm");
testInputFormat[0].setLenient(false);
testInputFormat[1].setLenient(false);
Date time;
for (int i = 0; i < testInputFormat.length; i++) {
try {
time = testInputFormat[i].parse(inputTime);
return returnFormat.format(time);
} catch (ParseException e) {
continue;
}
}
return "";
}
What should I change to fix this problem?
答案1
得分: 2
这个工作正常。
import java.text.SimpleDateFormat;
public class HelloWorld {
public static void main(String[] args) throws Exception {
final SimpleDateFormat parser = new SimpleDateFormat("hh:mm aa");
final SimpleDateFormat printer = new SimpleDateFormat("HH:mm");
System.out.println(printer.format(parser.parse("4:07 pm")));
}
}
你的代码看起来很好,所以我认为问题在其他地方。
英文:
This works as expected.
import java.text.SimpleDateFormat;
public class HelloWorld{
public static void main(String []args) throws Exception {
final SimpleDateFormat parser = new SimpleDateFormat("hh:mm aa");
final SimpleDateFormat printer = new SimpleDateFormat("HH:mm");
System.out.println(printer.format(parser.parse("4:07 pm")));
}
}
Your code looks good so I think problem is elsewhere.
答案2
得分: 1
I fixed my problem by referring to this post: https://stackoverflow.com/questions/16871367/java-text-parseexception-unparseable-date
The problem is, the default language of my computer is not English, so take Alexander's response as an example. I need to write:
import java.text.SimpleDateFormat;
import java.util.Locale;
public class HelloWorld {
public static void main(String []args) throws Exception {
final SimpleDateFormat parser = new SimpleDateFormat("hh:mm aa", Locale.ENGLISH);
final SimpleDateFormat printer = new SimpleDateFormat("HH:mm");
System.out.println(printer.format(parser.parse("4:07 pm")));
}
}
Note the "Locale.ENGLISH" in parser!
英文:
I fixed my problem by referring to this post: https://stackoverflow.com/questions/16871367/java-text-parseexception-unparseable-date
The problem is, the default language of my computer is not English, so take Alexander's response as an example. I need to write:
import java.text.SimpleDateFormat;
import java.util.Locale;
public class HelloWorld{
public static void main(String []args) throws Exception {
final SimpleDateFormat parser = new SimpleDateFormat("hh:mm aa", Locale.ENGLISH);
final SimpleDateFormat printer = new SimpleDateFormat("HH:mm");
System.out.println(printer.format(parser.parse("4:07 pm")));
}
}
Note the "Locale.ENGLISH" in parser!
答案3
得分: 0
确保在日期/时间包含字母时,使用带有Locale的日期/时间格式化API,因为不同的语言环境对字母有不同的表示方式。
import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Locale;
public class Main {
public static void main(String[] args) throws ParseException {
DateFormat stfInput = new SimpleDateFormat("h:m a", Locale.ENGLISH);// 12小时制
DateFormat stfOutput = new SimpleDateFormat("HH:mm", Locale.ENGLISH);// 24小时制
Date time = stfInput.parse("02:57 AM");
System.out.println(stfOutput.format(time));
time = stfInput.parse("07:05 PM");
System.out.println(stfOutput.format(time));
}
}
**输出:**
02:57
19:05
**注意:** `java.util`日期时间类已过时且容易出错,同样如此的是它们的格式化API,`SimpleDateFormat`。我建议您完全停止使用它们,并切换到[现代日期时间API](https://www.oracle.com/technical-resources/articles/java/jf14-date-time.html)。在**[教程:日期时间](https://docs.oracle.com/javase/tutorial/datetime/index.html)**中了解有关现代日期时间API的更多信息。
如果您正在为Android项目进行此操作,且您的Android API级别仍不符合Java-8,请查看[通过解糖使用的Java 8+ API](https://developer.android.com/studio/write/java8-support-table)以及[如何在Android项目中使用ThreeTenABP](https://stackoverflow.com/questions/38922754/how-to-use-threetenabp-in-android-project)。
**使用现代日期时间API:**
import java.time.LocalTime;
import java.time.format.DateTimeFormatter;
import java.util.Locale;
public class Main {
public static void main(String[] args) {
DateTimeFormatter dtfInput = DateTimeFormatter.ofPattern("h:m a", Locale.ENGLISH);// 12小时制
DateTimeFormatter dtfOutput = DateTimeFormatter.ofPattern("HH:mm", Locale.ENGLISH);// 24小时制
LocalTime time = LocalTime.parse("02:57 AM", dtfInput);
System.out.println(time.format(dtfOutput));
time = LocalTime.parse("07:05 PM", dtfInput);
System.out.println(time.format(dtfOutput));
}
}
**输出:**
02:57
19:05
英文:
Make sure to use Locale
with date/time formatting API whenever the date/time contains letters because different locales have a different representation of letters.
import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Locale;
public class Main {
public static void main(String[] args) throws ParseException {
DateFormat stfInput = new SimpleDateFormat("h:m a", Locale.ENGLISH);// 12-hour format
DateFormat stfOutput = new SimpleDateFormat("HH:mm", Locale.ENGLISH);// 24-hour format
Date time = stfInput.parse("02:57 AM");
System.out.println(stfOutput.format(time));
time = stfInput.parse("07:05 PM");
System.out.println(stfOutput.format(time));
}
}
Output:
02:57
19:05
Note: java.util
date-time classes are outdated and error-prone and so is their formatting API, SimpleDateFormat
. I suggest you should stop using them completely and switch to the modern date-time API. Learn more about the modern date-time API at Trail: Date Time.
If you are doing it for your Android project and your Android API level is still not compliant with Java-8, check Java 8+ APIs available through desugaring and How to use ThreeTenABP in Android Project.
Using the modern date-time API:
import java.time.LocalTime;
import java.time.format.DateTimeFormatter;
import java.util.Locale;
public class Main {
public static void main(String[] args) {
DateTimeFormatter dtfInput = DateTimeFormatter.ofPattern("h:m a", Locale.ENGLISH);// 12-hour format
DateTimeFormatter dtfOutput = DateTimeFormatter.ofPattern("HH:mm", Locale.ENGLISH);// 24-hour format
LocalTime time = LocalTime.parse("02:57 AM", dtfInput);
System.out.println(time.format(dtfOutput));
time = LocalTime.parse("07:05 PM", dtfInput);
System.out.println(time.format(dtfOutput));
}
}
Output:
02:57
19:05
答案4
得分: 0
> 我应该改变什么来解决这个问题?
首先且最重要的是:我建议你在处理时间时使用现代的 Java 日期和时间 API,即 java.time
。你尝试使用的 SimpleDateFormat
和 Date
这些日期时间类设计较差且早已过时。现代的 API 在使用上要舒服得多。Arvind Kumar Avinash 在回答的后半部分展示了如何使用。我没必要重复那部分内容。是的,Arvind 的代码确实修复了你的问题。
你的代码出了什么问题?
有人说过你的问题在于没有向格式化器提供英语环境。这在一部分上是正确的,但它并不能完全解释为什么 07:05 PM
被转换成了 07:05
,而正确的转换应该是 19:05
。
发生的事情是,你的第一个输入格式化器,即模式为 hh:mm aa
的那个,在解析时失败了,因为它使用了一个不叫做 PM
的语言。接下来,第二个模式为 HH:mm
的格式化器 成功 解析了字符串。令人惊讶,不是吗?我认为这是 SimpleDateFormat
的许多令人困惑的特点之一,它并不一定会解析整个字符串。它将 07:05
部分解析为小时(一天的小时)和分钟。然后它忽略了剩余的部分。这样,你得到了错误的结果 07:05
,而正确的应该是 19:05
。这仅仅是为什么你不应该使用 SimpleDateFormat
的众多原因之一。
链接
- Oracle 教程:日期和时间,解释了如何使用
java.time
。 - 相关问题:
- Java SimpleDateFormat 抛出 ParseException:在 Windows 上不可解析的日期,但在 Mac 上可以 [重复],关于解析上午和下午的区域设置问题。我显然推荐使用 Basil Bourque 的答案,使用
java.time
。 - SimpleDateFormat 解析(string str)当 str = 2011/12/12aaaaaaaaa 时不会抛出异常?,关于
SimpleDateFormat
不会解析整个字符串的问题。可以受到 David 的答案 的启发,使用java.time
以简单直接的方式解决问题。 - 强制 SimpleDateFormat 解析整个字符串,在我看来,这与你的问题相似。
- 在 Java 中将12小时制时间转换为24小时制。我推荐使用 Cloud 的答案,使用
java.time
。
- Java SimpleDateFormat 抛出 ParseException:在 Windows 上不可解析的日期,但在 Mac 上可以 [重复],关于解析上午和下午的区域设置问题。我显然推荐使用 Basil Bourque 的答案,使用
英文:
> What should I change to fix this problem?
First and most importantly: I recommend that you use java.time, the modern Java date and time API, for your time work. The date-time classes that you tried to use, SimpleDateFormat
and Date
, are poorly designed and long outdated. The modern API is so much nicer to work with. The last half of the answer by Arvind Kumar Avinash shows you how. There is no reason for me to repeat it. And yes, Arvind’s code does fix your problem.
What went wrong in your code?
It’s been said that your problem is not providing an English-speaking locale to your formatter. This is part of the truth, but it doesn’t fully explain why 07:05 PM
was converted to 07:05
where the correct conversion would have given 19:05
.
What happened was that your first input formatter, the one with pattern hh:mm aa
, failed at parsing because it used a language where PM
would be called something else. Next the second formatter, with pattern HH:mm
succeeded in parsing the string. Surprising, isn’t it? I consider it one of the many confusing traits of SimpleDateFormat
that it doesn’t necessarily parse the entire string. It parsed the 07:05
part as hour of day and minute. Then it ignored the remainder of the string. In this way you got the result 07:05
, which is incorrect, instead of the correct 19:05
. This is just one of the reasons why you shouldn’t use SimpleDateFormat
at all.
Links
- Oracle tutorial: Date Time explaining how to use java.time.
- Related questions:
- Java SimpleDateFormat throwing ParseException: Unparseable date on Windows but not on Mac [duplicate] about locale for parsing AM an PM. I obviously recommend the answer by Basil Bourque using java.time.
- SimpleDateFormat parse(string str) doesn't throw an exception when str = 2011/12/12aaaaaaaaa? about
SimpleDateFormat
not parsing the entire string. Be inspired by the answer by David using java.time to solve the problem in an easy and straightforward way. - Force SimpleDateFormat to parse the whole string, which seems to me to be similar to yours.
- Conversion from 12 hours time to 24 hours time in java. I recommend the answer by Cloud using java.time.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论