Java 字符串到日期的转换

2022-08-31 04:01:12

在 Java 中将格式为“2010 年 1 月 2 日”的 a 转换为 a 的最佳方法是什么?StringDate

最终,我想将月份,日期和年份分解为整数,以便我可以使用

Date date = new Date();
date.setMonth()..
date.setYear()..
date.setDay()..
date.setlong currentTime = date.getTime();

将日期转换为时间。


答案 1

这是一条艰难的道路,自Java 1.1(1997)以来,这些setter方法已被弃用。此外,自在Java 8(2014)中引入API以来,整个类实际上已被弃用(不建议)。java.util.Datejava.util.Datejava.time

只需使用日期时间格式器格式化日期,并使用与输入字符串匹配的模式(此处提供了教程)。

在“2010 年 1 月 2 日”作为输入字符串的特定情况下:

  1. “一月”是全文月份,因此请使用它的模式MMMM
  2. “2”是月份中的短日期,因此请使用该模式。d
  3. “2010”是 4 位数的年份,因此请使用该模式。yyyy
String string = "January 2, 2010";
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("MMMM d, yyyy", Locale.ENGLISH);
LocalDate date = LocalDate.parse(string, formatter);
System.out.println(date); // 2010-01-02

注意:如果你的格式模式碰巧也包含时间部分,那么使用LocalDateTime#parse(text,formatter)而不是LocalDate#parse(text,formatter)。而且,如果你的格式模式碰巧也包含时区,那么请改用ZonedDateTime#parse(text,formatter)。

以下是来自javadoc的相关摘录,列出了所有可用的格式模式:

象征 意义 介绍 例子
G 时代 发短信 AD;阿诺多米尼;一个
u 2004;04
y 年年 2004;04
D 一年中的某一天 189
M/L 一年中的月份 数字/文本 7;07;七月;七月;J
d 月中的某一天 10
Q/q 年同期 数字/文本 3;03;问题 3;第三季度
Y 基于周的年份 1996;96
w 基于周的年 27
W 每月一周 4
E 星期几 发短信 星期二;星期二;T
e/c 本地化的星期几 数字/文本 2;32 倍星期二;星期二;T
F 每月一周 3
a 上午-下午 发短信 下午
h 时钟-上午-小时-下午 (1-12) 12
K 上午一小时至下午 (0-11) 0
k 时钟-上午-小时-下午 (1-24) 0
H 一天中的一小时 (0-23) 0
m 每小时一分钟 30
s 分钟秒 55
S 秒数分数 分数 978
A 天毫 1234
n 纳秒 987654321
N 纳米日 1234000000
V 时区标识 区域标识 美洲/Los_Angeles;Z;-08:30
z 时区名称 区域名称 太平洋标准时间;太平洋标准时间
O 局部区域偏移 偏移量-O 格林尼治标准时间+8;格林尼治标准时间+08:00;世界标准时间-08:00;
X 零的区域偏移“Z” 偏移量-X Z;-08;-0830;-08:30;-083015;-08:30:15;
x 区域偏移 偏移量-x +0000;-08;-0830;-08:30;-083015;-08:30:15;
Z 区域偏移 偏移量-Z +0000;-0800;-08:00;

请注意,它有几个预定义的格式化程序,用于更流行的模式。因此,您可以使用 .这是可能的,因为它们与 线程安全相反。因此,如有必要,您也可以定义自己的定义。DateTimeFormatter.ofPattern("EEE, d MMM yyyy HH:mm:ss Z", Locale.ENGLISH);DateTimeFormatter.RFC_1123_DATE_TIMESimpleDateFormat

对于特定的输入字符串格式,您不需要使用显式:标准的ISO 8601日期,如2016-09-26T17:44:57Z,可以直接使用LocalDateTime#parse(text)进行解析,因为它已经使用了ISO_LOCAL_DATE_TIME格式化程序。类似地,LocalDate#parse(text)解析不带时间组件的ISO日期(参见ISO_LOCAL_DATE),ZonedDateTime#parse(text)解析添加偏移量和时区的ISO日期(参见ISO_ZONED_DATE_TIME)。DateTimeFormatter


Java 8 之前的版本

如果您还没有使用 Java 8,或者被迫使用 ,则使用 SimpleDateFormat 使用与输入字符串匹配的格式模式来格式化日期。java.util.Date

String string = "January 2, 2010";
DateFormat format = new SimpleDateFormat("MMMM d, yyyy", Locale.ENGLISH);
Date date = format.parse(string);
System.out.println(date); // Sat Jan 02 00:00:00 GMT 2010

请注意显式参数的重要性。如果省略它,则它将使用默认区域设置,该区域设置不一定是输入字符串的月份名称中使用的英语。如果区域设置与输入字符串不匹配,则即使格式模式似乎有效,您也会感到困惑地获得。Localejava.text.ParseException

以下是来自javadoc的相关摘录,列出了所有可用的格式模式:

日期或时间组件 介绍 例子
G 时代标志 发短信 广告
y 1996;96
Y 周年 2009;09
M/L 年中的月 七月;七月;07
w 一年中的一周 27
W 周月 2
D 一年中的一天 189
d 月中的某一天 10
F 星期几(每月) 2
E 星期几 发短信 星期二;星期二
u 星期几 1
a 上午/下午标记 发短信 下午
H 一天中的小时 (0-23) 0
k 一天中的小时 (1-24) 24
K 上午/下午时间 (0-11) 0
h 上午/下午时间 (1-12) 12
m 分钟(小时) 30
s 分钟秒 55
S 毫秒 978
z 时区 一般时区 太平洋标准时间;PST;格林尼治标准时间-08:00
Z 时区 RFC 822 时区 -0800
X 时区 ISO 8601 时区 -08;-0800;-08:00

请注意,这些模式区分大小写,四个字符或更多字符的基于文本的模式表示完整形式;否则,如果可用,将使用简短或缩写形式。例如: 或更多是不必要的。MMMMM

以下是一些有效模式的示例,用于解析迄今为止的给定字符串:SimpleDateFormat

输入字符串 模式
2001.07.04 AD 在 12:08:56 PDT yyyy.MM.dd G 'at' HH:mm:ss z
星期三, 7月 4, '01 EEE, MMM d, ''yy
下午12:08 h:mm a
太平洋夏令时间中午 12 点 hh 'o''clock' a, zzzz
0:08 下午, 太平洋夏令时 K:mm a, z
02001.七月.04 AD 12:08 下午 yyyyy.MMMM.dd GGG hh:mm aaa
星期三, 4 七月 2001 12:08:56 -0700 EEE, d MMM yyyy HH:mm:ss Z
010704120856-0700 yyMMddHHmmssZ
2001-07-04T12:08:56.235-0700 yyyy-MM-dd'T'HH:mm:ss.SSSZ
2001-07-04T12:08:56.235-07:00 yyyy-MM-dd'T'HH:mm:ss.SSSXXX
2001-W27-3 YYYY-'W'ww-u

一个重要的注意事项是,这不是线程安全的。换句话说,您永远不应该将其声明并分配为静态或实例变量,然后从不同的方法/线程中重用它。您应该始终在方法本地范围内全新创建它。SimpleDateFormat


答案 2

啊,是的,Java日期讨论,再次。为了处理日期操作,我们使用DateCalendarGregorianCalendarSimpleDateFormat。例如,使用 1 月日期作为输入:

Calendar mydate = new GregorianCalendar();
String mystring = "January 2, 2010";
Date thedate = new SimpleDateFormat("MMMM d, yyyy", Locale.ENGLISH).parse(mystring);
mydate.setTime(thedate);
//breakdown
System.out.println("mydate -> "+mydate);
System.out.println("year   -> "+mydate.get(Calendar.YEAR));
System.out.println("month  -> "+mydate.get(Calendar.MONTH));
System.out.println("dom    -> "+mydate.get(Calendar.DAY_OF_MONTH));
System.out.println("dow    -> "+mydate.get(Calendar.DAY_OF_WEEK));
System.out.println("hour   -> "+mydate.get(Calendar.HOUR));
System.out.println("minute -> "+mydate.get(Calendar.MINUTE));
System.out.println("second -> "+mydate.get(Calendar.SECOND));
System.out.println("milli  -> "+mydate.get(Calendar.MILLISECOND));
System.out.println("ampm   -> "+mydate.get(Calendar.AM_PM));
System.out.println("hod    -> "+mydate.get(Calendar.HOUR_OF_DAY));

然后,您可以使用如下方式对其进行操作:

Calendar now = Calendar.getInstance();
mydate.set(Calendar.YEAR,2009);
mydate.set(Calendar.MONTH,Calendar.FEBRUARY);
mydate.set(Calendar.DAY_OF_MONTH,25);
mydate.set(Calendar.HOUR_OF_DAY,now.get(Calendar.HOUR_OF_DAY));
mydate.set(Calendar.MINUTE,now.get(Calendar.MINUTE));
mydate.set(Calendar.SECOND,now.get(Calendar.SECOND));
// or with one statement
//mydate.set(2009, Calendar.FEBRUARY, 25, now.get(Calendar.HOUR_OF_DAY), now.get(Calendar.MINUTE), now.get(Calendar.SECOND));
System.out.println("mydate -> "+mydate);
System.out.println("year   -> "+mydate.get(Calendar.YEAR));
System.out.println("month  -> "+mydate.get(Calendar.MONTH));
System.out.println("dom    -> "+mydate.get(Calendar.DAY_OF_MONTH));
System.out.println("dow    -> "+mydate.get(Calendar.DAY_OF_WEEK));
System.out.println("hour   -> "+mydate.get(Calendar.HOUR));
System.out.println("minute -> "+mydate.get(Calendar.MINUTE));
System.out.println("second -> "+mydate.get(Calendar.SECOND));
System.out.println("milli  -> "+mydate.get(Calendar.MILLISECOND));
System.out.println("ampm   -> "+mydate.get(Calendar.AM_PM));
System.out.println("hod    -> "+mydate.get(Calendar.HOUR_OF_DAY));