Java字符串到日期的转换

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

最后,我想将月、日和年分解为整数,以便我可以使用

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

将日期转换为时间。

2319613 次浏览

这是一条艰难的道路,自Java1.1(1997)以来,这些java.util.Date setter方法已被弃用。此外,自Java8(2014)引入java.time API以来,整个java.util.Date类实际上已被弃用(不推荐)。

只需使用DateTimeFormatter将日期格式化为与输入字符串匹配的模式(该教程可在此处获得)。

在您的特定情况下,“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; Anno Domini; A
u2004年;04
y纪元年2004年;04
D年度日数量189
M/L编号/文字7; 07; Jul;七月;J
d月环比数量10
Q/q季度编号/文字3; 03; Q3;第三季度
Y周-年1996年;96
w按周计算的年份数量27
W月周数数量4
E星期几文本星期二,星期二
e/c本地化星期几编号/文字2; 02;星期二;T
时钟-小时-上午-下午(1-24)数量
H小时(0-23)数量
m每小时分钟数量30
s秒级数量55
S秒分数分数978
A毫日数量1234
n纳秒数量987654321
N纳米级数量1234000000
V时区ID专区名称美洲/Los_Angeles; Z;-08:30
z时区名称区域名称太平洋标准时间;太平洋标准时间
O局部区域偏移O偏移量GMT+8; GMT+08:00; UTC-08:00;
X零的区域偏移“Z”偏移量-xZ;-08;-0830;-08:30;-083015;-08:30:15;
x区域偏移偏移量-x


Java8

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

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

请注意显式Locale参数的重要性。如果您省略它,那么它将使用默认语言环境,它不一定是输入字符串月份名称中使用的英语。如果区域设置与输入字符串不匹配,那么即使格式模式看起来有效,您也会混淆地得到java.text.ParseException

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

日期或时间组件演示文稿示例
G纪元代号文本AD
y1996年;96
Y周年2009年;09
M/L一年中的月份七月;七月;07
w一年中的一周数量27
W每个月的一周数量2
D一年中的每一天数量189
d日复一日数量10
F月中的星期几数量2
E日复一日文本星期二;星期二
小时(0-23)数量
k一天中的一小时(1-24)数量24
K小时在上午/下午(0-11)数量
h小时上午/下午(1-12)数量12
m一小时一分钟数量30
s第二分钟数量55
S毫秒数量978
z时区一般时区太平洋标准时间;太平洋标准时间;格林尼治标准时间-08:00
Z时区RFC 822时区-0800
X时区ISO 8601时区-08;-0800;-08:00

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

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

输入字符串模式
2001.07.04 AD at 12:08:56 PDTyyyy.MM.dd G 'at' HH:mm:ss z
2001年7月4日星期三EEE, MMM d, ''yy
12:08 PMh:mm a
下午12点太平洋夏令时
yyyy-MM-dd'T'HH:mm:ss.SSSZ
2001-07-04 T 12:08:56.235-07:00yyyy-MM-dd'T'HH:mm:ss.SSSXXX
2001-W27-3YYYY-'W'ww-u

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

啊,是的,Java日期讨论,再次。为了处理日期操作,我们使用日期日历格里高利日历SimpleDateFormat简单日期格式。例如使用您的一月日期作为输入:

Calendar mydate = new GregorianCalendar();String mystring = "January 2, 2010";Date thedate = new SimpleDateFormat("MMMM d, yyyy", Locale.ENGLISH).parse(mystring);mydate.setTime(thedate);//breakdownSystem.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));

在处理SimpleDateFormat类时,重要的是要记住Date不是线程安全的,您不能与多个线程共享单个Date对象。

此外,“m”和“M”之间也有很大的区别,其中小写用于分钟,大写用于月份。“d”和“D”也是如此。这可能会导致经常被忽视的微妙错误。有关更多详细信息,请参阅Javadoc在Java中将字符串转换为日期的指南

此外,SimpleDateFormat不适用于某些客户端技术,例如GWT

使用Calendar.get实例()是个好主意,您的要求是比较两个日期;使用长日期。

String str_date = "11-June-07";DateFormat formatter = new SimpleDateFormat("dd-MMM-yy");Date date = formatter.parse(str_date);
DateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd");Date date;try {date = dateFormat.parse("2013-12-4");System.out.println(date.toString()); // Wed Dec 04 00:00:00 CST 2013
String output = dateFormat.format(date);System.out.println(output); // 2013-12-04}catch (ParseException e) {e.printStackTrace();}

这对我来说很好。

虽然有些答案在技术上是正确的,但并不可取。

  • 日期和日历类java.util.是出了名的麻烦。由于设计和实现中的缺陷,请避免它们。幸运的是,我们可以选择另外两个优秀的日期时间库:
    • Joda-Time
      这个流行的开源免费库可以跨多个版本的Java使用。StackOverflow上可以找到许多使用它的示例。阅读其中的一些将有助于您快速上手。
    • java.time.包
      这组新的类受到Joda-Time的启发,并由JSR 310定义。这些类内置在Java8中。一个项目正在将这些类反向移植到Java7,但该反向移植不受Oracle的支持。
  • 正如克里斯托弗·约翰逊在他对这个问题的评论中正确指出的那样,其他答案忽略了以下重要问题:
    • 一天的时间
      Date有日期部分和时间部分。
    • 时区
      一天的开始取决于时区。如果您未能指定时区,则应用JVM的默认时区。这意味着您的代码在其他计算机上运行或修改时区设置时的行为可能会发生变化。可能不是您想要的。
    • 区域设置
      区域设置的语言指定了如何解释解析过程中遇到的单词(月份和日期的名称)。(BalusC的回答正确处理了这一点。)此外,在生成日期时间的字符串表示时,区域设置会影响一些格式化程序的输出。

Joda-Time

下面是关于Joda-Time的一些说明。

时区

Joda-Time中,时间戳对象真正知道自己分配的时区。这与java.util.Date类形成对比,后者似乎有时区但没有。

请注意下面的示例代码,我们是如何将时区对象传递给解析字符串的格式化程序的。该时区用于将日期时间解释为发生在该时区。因此,您需要考虑并确定该字符串输入表示的时区。

由于您的输入字符串中没有时间部分,Joda-Time将指定时区当天的第一个时刻分配为一天中的时间。通常这意味着00:00:00,但并非总是如此,因为夏令时(DST)或其他异常。顺便说一句,您可以通过调用withTimeAtStartOfDay对任何DateTime实例执行相同的操作。

格式模式

格式化程序模式中使用的字符在Joda-Time中与java.util.日期/日历中的相似,但不完全相同。请仔细阅读文档。

不变性

我们通常使用Joda-Time中的不可变类。我们不会修改现有的Date-Time对象,而是调用基于另一个对象创建新实例的方法,并复制大多数方面,除非需要更改。一个例子是下面最后一行对withZone的调用。不变性有助于使Joda-Time非常线程安全,也可以使一些工作更加清晰。

转换

您将需要java.util.Date对象与其他不了解Joda-Time对象的类/框架一起使用。幸运的是,来回移动非常容易。

从java.util.Date对象(这里命名为date)到Joda-Time DateTime…

org.joda.time.DateTime dateTime = new DateTime( date, timeZone );

从Joda-Time到java.util.Date对象的另一个方向…

java.util.Date date = dateTime.toDate();

示例代码

String input = "January 2, 2010";
java.util.Locale locale = java.util.Locale.US;DateTimeZone timeZone = DateTimeZone.forID( "Pacific/Honolulu" ); // Arbitrarily chosen for example.DateTimeFormatter formatter = DateTimeFormat.forPattern( "MMMM d, yyyy" ).withZone( timeZone ).withLocale( locale );DateTime dateTime = formatter.parseDateTime( input );
System.out.println( "dateTime: " + dateTime );System.out.println( "dateTime in UTC/GMT: " + dateTime.withZone( DateTimeZone.UTC ) );

当运行…

dateTime: 2010-01-02T00:00:00.000-10:00dateTime in UTC/GMT: 2010-01-02T10:00:00.000Z

使用Java8,我们获得了一个新的日期/时间API(JSR 310)。

以下方法可用于解析Java8中的日期,而不依赖于Joda-Time

 String str = "January 2nd, 2010";

// if we 2nd even we have changed in pattern also it is not working please workout with 2ndDateTimeFormatter formatter = DateTimeFormatter.ofPattern("MMMM Q, yyyy", Locale.ENGLISH);LocalDate date = LocalDate.parse(str, formatter);

// access date fieldsint year = date.getYear(); // 2010int day = date.getDayOfMonth(); // 2Month month = date.getMonth(); // JANUARYint monthAsInt = month.getValue(); // 1

本地日期是表示日期(不带时间)的标准Java8类。如果您想解析包含日期和时间信息的值,则应使用本地时间当前时间。对于具有时区的值,请使用指定日期和时间。两者都提供了类似于LocalDateparse()方法:

LocalDateTime dateWithTime = LocalDateTime.parse(strWithDateAndTime, dateTimeFormatter);ZonedDateTime zoned = ZonedDateTime.parse(strWithTimeZone, zoneFormatter);

日期时间格式Javadoc中的列表格式化字符:

All letters 'A' to 'Z' and 'a' to 'z' are reserved as pattern letters.The following pattern letters are defined:
Symbol  Meaning                     Presentation      Examples------  -------                     ------------      -------G       era                         text              AD; Anno Domini; Au       year                        year              2004; 04y       year-of-era                 year              2004; 04D       day-of-year                 number            189M/L     month-of-year               number/text       7; 07; Jul; July; Jd       day-of-month                number            10
Q/q     quarter-of-year             number/text       3; 03; Q3; 3rd quarterY       week-based-year             year              1996; 96w       week-of-week-based-year     number            27W       week-of-month               number            4E       day-of-week                 text              Tue; Tuesday; Te/c     localized day-of-week       number/text       2; 02; Tue; Tuesday; TF       week-of-month               number            3
a       am-pm-of-day                text              PMh       clock-hour-of-am-pm (1-12)  number            12K       hour-of-am-pm (0-11)        number            0k       clock-hour-of-am-pm (1-24)  number            0
H       hour-of-day (0-23)          number            0m       minute-of-hour              number            30s       second-of-minute            number            55S       fraction-of-second          fraction          978A       milli-of-day                number            1234n       nano-of-second              number            987654321N       nano-of-day                 number            1234000000
V       time-zone ID                zone-id           America/Los_Angeles; Z; -08:30z       time-zone name              zone-name         Pacific Standard Time; PSTO       localized zone-offset       offset-O          GMT+8; GMT+08:00; UTC-08:00;X       zone-offset 'Z' for zero    offset-X          Z; -08; -0830; -08:30; -083015; -08:30:15;x       zone-offset                 offset-x          +0000; -08; -0830; -08:30; -083015; -08:30:15;Z       zone-offset                 offset-Z          +0000; -0800; -08:00;

我的简陋测试程序。我用它来玩格式化程序和查找我在日志文件中找到的长日期(但谁把它们放在那里…)。

我的测试程序:

package be.test.package.time;
import java.text.DateFormat;import java.text.ParseException;import java.text.SimpleDateFormat;import java.util.ArrayList;import java.util.Date;import java.util.List;import java.util.TimeZone;
public class TimeWork {
public static void main(String[] args) {
TimeZone timezone = TimeZone.getTimeZone("UTC");
List<Long> longs = new ArrayList<>();List<String> strings = new ArrayList<>();
//Formatting a date needs a timezone - otherwise the date get formatted to your system time zone.//Use 24h format HH. In 12h format hh can be in range 0-11, which makes 12 overflow to 0.DateFormat formatter = new SimpleDateFormat("dd-MM-yyyy HH:mm:ss.SSS");formatter.setTimeZone(timezone);
Date now = new Date();
//Test datesstrings.add(formatter.format(now));strings.add("01-01-1970 00:00:00.000");strings.add("01-01-1970 00:00:01.000");strings.add("01-01-1970 00:01:00.000");strings.add("01-01-1970 01:00:00.000");strings.add("01-01-1970 10:00:00.000");strings.add("01-01-1970 12:00:00.000");strings.add("01-01-1970 24:00:00.000");strings.add("02-01-1970 00:00:00.000");strings.add("01-01-1971 00:00:00.000");strings.add("01-01-2014 00:00:00.000");strings.add("31-12-1969 23:59:59.000");strings.add("31-12-1969 23:59:00.000");strings.add("31-12-1969 23:00:00.000");
//Test datalongs.add(now.getTime());longs.add(-1L);longs.add(0L); //Long date presentation at - midnight 1/1/1970 UTC - The timezone is important!longs.add(1L);longs.add(1000L);longs.add(60000L);longs.add(3600000L);longs.add(36000000L);longs.add(43200000L);longs.add(86400000L);longs.add(31536000000L);longs.add(1388534400000L);longs.add(7260000L);longs.add(1417706084037L);longs.add(-7260000L);
System.out.println("===== String to long =====");
//Show the long value of the datefor (String string: strings) {try {Date date = formatter.parse(string);System.out.println("Formated date : " + string + " = Long = " + date.getTime());} catch (ParseException e) {e.printStackTrace();}}
System.out.println("===== Long to String =====");
//Show the date behind the longfor (Long lo : longs) {Date date = new Date(lo);String string = formatter.format(date);System.out.println("Formated date : " + string + " = Long = " + lo);}}}

测试结果:

===== String to long =====Formated date : 05-12-2014 10:17:34.873 = Long = 1417774654873Formated date : 01-01-1970 00:00:00.000 = Long = 0Formated date : 01-01-1970 00:00:01.000 = Long = 1000Formated date : 01-01-1970 00:01:00.000 = Long = 60000Formated date : 01-01-1970 01:00:00.000 = Long = 3600000Formated date : 01-01-1970 10:00:00.000 = Long = 36000000Formated date : 01-01-1970 12:00:00.000 = Long = 43200000Formated date : 01-01-1970 24:00:00.000 = Long = 86400000Formated date : 02-01-1970 00:00:00.000 = Long = 86400000Formated date : 01-01-1971 00:00:00.000 = Long = 31536000000Formated date : 01-01-2014 00:00:00.000 = Long = 1388534400000Formated date : 31-12-1969 23:59:59.000 = Long = -1000Formated date : 31-12-1969 23:59:00.000 = Long = -60000Formated date : 31-12-1969 23:00:00.000 = Long = -3600000===== Long to String =====Formated date : 05-12-2014 10:17:34.873 = Long = 1417774654873Formated date : 31-12-1969 23:59:59.999 = Long = -1Formated date : 01-01-1970 00:00:00.000 = Long = 0Formated date : 01-01-1970 00:00:00.001 = Long = 1Formated date : 01-01-1970 00:00:01.000 = Long = 1000Formated date : 01-01-1970 00:01:00.000 = Long = 60000Formated date : 01-01-1970 01:00:00.000 = Long = 3600000Formated date : 01-01-1970 10:00:00.000 = Long = 36000000Formated date : 01-01-1970 12:00:00.000 = Long = 43200000Formated date : 02-01-1970 00:00:00.000 = Long = 86400000Formated date : 01-01-1971 00:00:00.000 = Long = 31536000000Formated date : 01-01-2014 00:00:00.000 = Long = 1388534400000Formated date : 01-01-1970 02:01:00.000 = Long = 7260000Formated date : 04-12-2014 15:14:44.037 = Long = 1417706084037Formated date : 31-12-1969 21:59:00.000 = Long = -7260000

我们使用的两个简单格式化程序:

  1. 我们想要哪种格式的日期?
  2. 实际存在哪种格式的日期?

我们解析完整的日期到时间格式:

date="2016-05-06 16:40:32";
public static String setDateParsing(String date) throws ParseException {
// This is the format date we wantDateFormat mSDF = new SimpleDateFormat("hh:mm a");
// This format date is actually presentSimpleDateFormat formatter = new SimpleDateFormat("yyyy-mm-dd hh:mm");return mSDF.format(formatter.parse(date));}

试试这个

String date = get_pump_data.getString("bond_end_date");DateFormat format = new SimpleDateFormat("yyyy-MM-dd", Locale.ENGLISH);Date datee = (Date)format.parse(date);

您可以使用SimpleDateform将字符串更改为日期

SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");String strDate = "2000-01-01";Date date = sdf.parse(strDate);

Source链接

对于android

Calendar.get实例给出

Thu Jul 26 15:54:13 GMT+05:30 2018

使用

String oldDate = "Thu Jul 26 15:54:13 GMT+05:30 2018";DateFormat format = new SimpleDateFormat("EEE LLL dd HH:mm:ss Z yyyy");Date updateLast = format.parse(oldDate);

字符串到日期的转换:

private Date StringtoDate(String date) throws Exception {SimpleDateFormat sdf1 = new SimpleDateFormat("yyyy-MM-dd");java.sql.Date sqlDate = null;if( !date.isEmpty()) {
try {java.util.Date normalDate = sdf1.parse(date);sqlDate = new java.sql.Date(normalDate.getTime());} catch (ParseException e) {throw new Exception("Not able to Parse the date", e);}}return sqlDate;}
DateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss");Date date1 = null;Date date2 = null;
try {date1 = dateFormat.parse(t1);date2 = dateFormat.parse(t2);} catch (ParseException e) {e.printStackTrace();}DateFormat formatter = new SimpleDateFormat("dd-MMM-yyyy");String StDate = formatter.format(date1);String edDate = formatter.format(date2);
System.out.println("ST  "+ StDate);System.out.println("ED "+ edDate);
从日期到字符串
SimpleDateFormat sdf = new SimpleDateFormat("dd-MM-yyyy");return sdf.format(date);
从字符串到日期
SimpleDateFormat sdf = new SimpleDateFormat(datePattern);return sdf.parse(dateStr);
从日期字符串到不同格式
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");SimpleDateFormat newSdf = new SimpleDateFormat("dd-MM-yyyy");Date temp = sdf.parse(dateStr);return newSdf.format(temp);

来源链接

我致力于将String解析为LocalDateTime。我把它留在这里作为示例

LocalDateTime d = LocalDateTime.parse("20180805 101010", DateTimeFormatter.ofPattern("yyyyMMdd HHmmss"));

我得到了输入图片描述