Javastring到date的转换
有人可以推荐最好的方式来转换格式'2010年1月2日'的string中的date在java? 最终,我想把整个月份,每天,每一年作为整数,以便我可以使用:
Date date = new Date(); date.setMonth().. date.setYear().. date.setDay().. date.setlong currentTime = date.getTime();
将date转换为时间。
不要这样做,这是困难的方式。 而且,从Java 1.1(1997)开始,这些java.util.Date
setter方法被弃用了。 使用与inputstring匹配的格式模式,使用SimpleDateFormat
简单地格式化date 。
在你的“2010年1月2日”的具体情况下inputstring,“1月”是全文月,所以使用MMMM
模式,“2”是短date,所以使用d
模式, “2010”是4位数字的年份,所以使用yyyy
格式。
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
参数的重要性。 如果省略它,那么它将使用默认语言环境 ,该语言环境不一定是inputstring的月份名称中使用的英语。 如果语言环境与inputstring不匹配,那么即使格式模式看起来有效,您也会混淆得到java.text.ParseException
。
以下是javadoc的相关摘录,列出了所有可用的格式模式:
Letter Date or Time Component Presentation Examples ------ ---------------------- ------------------ ------------------------------------- G Era designator Text AD y Year Year 1996; 96 Y Week year Year 2009; 09 M/L Month in year Month July; Jul; 07 w Week in year Number 27 W Week in month Number 2 D Day in year Number 189 d Day in month Number 10 F Day of week in month Number 2 E Day in week Text Tuesday; Tue u Day number of week Number 1 a Am/pm marker Text PM H Hour in day (0-23) Number 0 k Hour in day (1-24) Number 24 K Hour in am/pm (0-11) Number 0 h Hour in am/pm (1-12) Number 12 m Minute in hour Number 30 s Second in minute Number 55 S Millisecond Number 978 z Time zone General time zone Pacific Standard Time; PST; GMT-08:00 Z Time zone RFC 822 time zone -0800 X Time zone ISO 8601 time zone -08; -0800; -08:00
请注意,模式区分大小写,并且基于4个或更多字符的文本模式表示完整forms,否则将使用简短forms或缩写forms(如果可用)。 所以如MMMMM
或更多是不必要的。
下面是一些有效的SimpleDateFormat
模式的例子来分析给定的stringdate:
Input string Pattern ------------------------------------ ---------------------------- 2001.07.04 AD at 12:08:56 PDT yyyy.MM.dd G 'at' HH:mm:ss z Wed, Jul 4, '01 EEE, MMM d, ''yy 12:08 PM h:mm a 12 o'clock PM, Pacific Daylight Time hh 'o''clock' a, zzzz 0:08 PM, PDT K:mm a, z 02001.July.04 AD 12:08 PM yyyyy.MMMM.dd GGG hh:mm aaa Wed, 4 Jul 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
不是线程安全的。 换句话说,你永远不要声明和分配它作为一个静态或实例variables,然后从不同的方法/线程重用。 您应该始终在方法的本地范围内创build全新的。
Java 8更新
如果你碰巧在Java 8上,然后使用DateTimeFormatter
(在这里也可以单击链接查看所有预定义的格式化程序和可用的格式模式; 本教程可以在这里find )。 这个新的API受到了JodaTime的启发。
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的相关摘录,列出了所有可用的格式模式:
Symbol Meaning Presentation Examples ------ -------------------------- ------------ ---------------------------------------------- G era text AD; Anno Domini; A u year year 2004; 04 y year-of-era year 2004; 04 D day-of-year number 189 M/L month-of-year number/text 7; 07; Jul; July; J d day-of-month number 10 Q/q quarter-of-year number/text 3; 03; Q3; 3rd quarter Y week-based-year year 1996; 96 w week-of-week-based-year number 27 W week-of-month number 4 E day-of-week text Tue; Tuesday; T e/c localized day-of-week number/text 2; 02; Tue; Tuesday; T F week-of-month number 3 a am-pm-of-day text PM h clock-hour-of-am-pm (1-12) number 12 K hour-of-am-pm (0-11) number 0 k clock-hour-of-am-pm (1-24) number 0 H hour-of-day (0-23) number 0 m minute-of-hour number 30 s second-of-minute number 55 S fraction-of-second fraction 978 A milli-of-day number 1234 n nano-of-second number 987654321 N nano-of-day number 1234000000 V time-zone ID zone-id America/Los_Angeles; Z; -08:30 z time-zone name zone-name Pacific Standard Time; PST O 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;
请注意,它有几个预定义的格式化为更stream行的模式。 因此,而不是例如DateTimeFormatter.ofPattern("EEE, d MMM yyyy HH:mm:ss Z", Locale.ENGLISH);
,你可以使用DateTimeFormatter.RFC_1123_DATE_TIME
。 这是可能的,因为它们与SimpleDateFormat
相反,是线程安全的。 如果有必要,你也可以定义你自己的。
对于特定的inputstring格式,您不需要使用明确的DateTimeFormatter
:像2016-09-26T17:44:57Z那样的标准ISO 8601date可以直接使用LocalDateTime#parse(text)
进行parsing,因为它已经使用ISO_LOCAL_DATE_TIME
格式化程序。 类似地, LocalDate#parse(text)
parsing没有时间组件的ISOdate(参见ISO_LOCAL_DATE
), ZonedDateTime#parse(text)
parsingISOdate并添加偏移量和时区(请参阅ISO_ZONED_DATE_TIME
)。
是的Javadate讨论,再次。 为了处理date操作,我们使用Date , Calendar , GregorianCalendar和SimpleDateFormat 。 例如使用你的一月份date作为input:
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));
String str_date="11-June-07"; DateFormat formatter ; Date date ; formatter = new SimpleDateFormat("dd-MMM-yy"); date = formatter.parse(str_date);
使用Java 8,我们得到了一个新的date/时间API( JSR 310 )。
下面的方法可以用来在不依赖Joda-Time的情况下parsingJava 8中的date:
String str = "January 2, 2010"; DateTimeFormatter formatter = DateTimeFormatter.ofPattern("MMMM d, yyyy", Locale.ENGLISH); LocalDate date = LocalDate.parse(str, formatter); // access date fields int year = date.getYear(); // 2010 int day = date.getDayOfMonth(); // 2 Month month = date.getMonth(); // JANUARY int monthAsInt = month.getValue(); // 1
LocalDate是表示date(没有时间)的标准Java 8类。 如果要parsing包含date和时间信息的值,则应使用LocalDateTime 。 对于时区的值使用ZonedDateTime 。 两者都提供了类似于LocalDate
的parse()
方法:
LocalDateTime dateWithTime = LocalDateTime.parse(strWithDateAndTime, dateTimeFormatter); ZonedDateTime zoned = ZonedDateTime.parse(strWithTimeZone, zoneFormatter);
来自DateTimeFormatter 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; A u year year 2004; 04 y year-of-era year 2004; 04 D day-of-year number 189 M/L month-of-year number/text 7; 07; Jul; July; J d day-of-month number 10 Q/q quarter-of-year number/text 3; 03; Q3; 3rd quarter Y week-based-year year 1996; 96 w week-of-week-based-year number 27 W week-of-month number 4 E day-of-week text Tue; Tuesday; T e/c localized day-of-week number/text 2; 02; Tue; Tuesday; T F week-of-month number 3 a am-pm-of-day text PM h clock-hour-of-am-pm (1-12) number 12 K hour-of-am-pm (0-11) number 0 k clock-hour-of-am-pm (1-24) number 0 H hour-of-day (0-23) number 0 m minute-of-hour number 30 s second-of-minute number 55 S fraction-of-second fraction 978 A milli-of-day number 1234 n nano-of-second number 987654321 N nano-of-day number 1234000000 V time-zone ID zone-id America/Los_Angeles; Z; -08:30 z time-zone name zone-name Pacific Standard Time; PST O 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;
尽pipe一些答案在技术上是正确的,但并不可取。
- java.util.Date&Calendar类是非常麻烦的。 由于devise和实现的缺陷,避免它们。 幸运的是,我们可以select另外两个优秀的date时间库:
- 乔达时间
这个stream行的开放源代码免费库可以在多个版本的Java中使用。 在StackOverflow上可以find它的用法的很多例子。 阅读其中的一些内容将有助于让你快速上手。 - java.time。*包
这套新的类受到Joda-Time的启发,由JSR 310定义。这些类是内置于Java 8中的。一个项目正在将这些类反向移植到Java 7,但是这种后端移植不是由Oracle支持的。
- 乔达时间
- 正如克里斯托弗·约翰逊在他对这个问题的评论中正确地指出的那样,
- 一天的时间
date既有date部分也有时间部分) - 时区
一天的开始取决于时区。 如果您未能指定时区,则应用JVM的默认时区。 这意味着在其他计算机上运行或修改时区设置时,代码的行为可能会发生变化。 可能不是你想要的。 - 语言环境
语言环境的语言指定如何解释在parsing期间遇到的单词(月份和date的名称)。 ( BalusC的答案正确地处理了这个问题。)另外,Locale在生成date时间的string表示时影响某些格式化程序的输出。
- 一天的时间
乔达时间
关于Joda-Time的一些注记如下。
时区
在Joda-Time中 , DateTime对象真正知道它自己分配的时区。 这与java.util.Date类似,但它似乎有一个时区,但没有。
请注意,在下面的示例代码中,我们如何将时区对象传递给parsingstring的格式器。 该时区用于将该date时间解释为发生在该时区中。 所以你需要考虑并确定该stringinput所代表的时区。
由于inputstring中没有时间部分,因此Joda-Time会将指定时区的一天中的第一个时刻指定为一天的时间。 通常这意味着00:00:00
但并不总是,因为夏令时(DST)或其他exception。 顺便说一下,您可以通过调用withTimeAtStartOfDay
对任何DateTime实例执行相同的withTimeAtStartOfDay
。
格式化程序模式
在Joda-Time中,格式化程序模式中使用的字符与java.util.Date/Calendar中的字符相似,但不完全相同。 仔细阅读文档。
不变性
我们通常在Joda-Time中使用不可变的类。 除了修改现有的Date-Time对象之外,我们还调用方法创build基于其他对象的新实例,除了需要更改外,大部分方面都被复制。 一个例子是在下面最后一行的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:00 dateTime in UTC/GMT: 2010-01-02T10:00:00.000Z
在处理SimpleDateFormat类时,重要的是要记住Date不是线程安全的,而且不能共享一个具有多个线程的Date对象。另外,在使用small case的“m”和“M”之间有很大的区别分钟和大写情况用于月份。 与“d”和“D”相同。 这可能会导致细微的错误,往往被忽视。 有关更多详细信息,请参阅Javadoc或指南以Java中的string转换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(); }
感谢海报。 更新的答案和testing更多。 它对我来说工作正常。 玩的开心! @。@
SimpleDateFormat也不适用于像gwt这样的客户端技术。 最好去Calendar.getInstance()和你的要求是比较两个date去长期date。
我谦虚的testing程序。 我用它来查找格式化程序,查找在日志文件中find的很长的date(但是谁把它们放在那里…)。
我的testing程序:
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 dates strings.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 data longs.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 date for (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 long for (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 = 1417774654873 Formated date : 01-01-1970 00:00:00.000 = Long = 0 Formated date : 01-01-1970 00:00:01.000 = Long = 1000 Formated date : 01-01-1970 00:01:00.000 = Long = 60000 Formated date : 01-01-1970 01:00:00.000 = Long = 3600000 Formated date : 01-01-1970 10:00:00.000 = Long = 36000000 Formated date : 01-01-1970 12:00:00.000 = Long = 43200000 Formated date : 01-01-1970 24:00:00.000 = Long = 86400000 Formated date : 02-01-1970 00:00:00.000 = Long = 86400000 Formated date : 01-01-1971 00:00:00.000 = Long = 31536000000 Formated date : 01-01-2014 00:00:00.000 = Long = 1388534400000 Formated date : 31-12-1969 23:59:59.000 = Long = -1000 Formated date : 31-12-1969 23:59:00.000 = Long = -60000 Formated date : 31-12-1969 23:00:00.000 = Long = -3600000 ===== Long to String ===== Formated date : 05-12-2014 10:17:34.873 = Long = 1417774654873 Formated date : 31-12-1969 23:59:59.999 = Long = -1 Formated date : 01-01-1970 00:00:00.000 = Long = 0 Formated date : 01-01-1970 00:00:00.001 = Long = 1 Formated date : 01-01-1970 00:00:01.000 = Long = 1000 Formated date : 01-01-1970 00:01:00.000 = Long = 60000 Formated date : 01-01-1970 01:00:00.000 = Long = 3600000 Formated date : 01-01-1970 10:00:00.000 = Long = 36000000 Formated date : 01-01-1970 12:00:00.000 = Long = 43200000 Formated date : 02-01-1970 00:00:00.000 = Long = 86400000 Formated date : 01-01-1971 00:00:00.000 = Long = 31536000000 Formated date : 01-01-2014 00:00:00.000 = Long = 1388534400000 Formated date : 01-01-1970 02:01:00.000 = Long = 7260000 Formated date : 04-12-2014 15:14:44.037 = Long = 1417706084037 Formated date : 31-12-1969 21:59:00.000 = Long = -7260000
简单的两个formtter我们使用
1)我们想要什么格式的date?
2)哪个格式的date实际存在?
我们parsing完整date到时间格式。
date =“2016-05-06 16:40:32”;
public static String setDateParsing(String date) throws ParseException { //this format date we want DateFormat mSDF = new SimpleDateFormat("hh:mm a"); //this format date actully present SimpleDateFormat formatter = new SimpleDateFormat("yyyy-mm-dd hh:mm"); return mSDF.format(formatter.parse(date)); }
我有一个任务,我必须写一个代码,将采取任何string,并尝试将其转换为date时,string的格式不提前知道。 我写了一个有趣的工具。 这里是描述这个想法的文章: Java 8 java.time包:parsing任何string到目前为止 。 这是在Java 8中实现的,但这个想法也可以在早期版本中实现
尝试这个
String date = get_pump_data.getString("bond_end_date"); DateFormat format = new SimpleDateFormat("yyyy-MM-dd", Locale.ENGLISH); Date datee = (Date)format.parse(date);
您可以使用SimpleDateformat更改stringdate
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd"); String strDate = "2000-01-01"; Date date= new Date(sdf.parse(strDate ).getTime());