Java 字符串到日期的转换

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/4216745/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-14 14:41:46  来源:igfitidea点击:

Java string to date conversion

javastringdatetimedata-conversion

提问by littleK

What is the best way to convert a Stringin the format 'January 2, 2010' to a Datein Java?

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

Ultimately, I want to break out the month, the day, and the year as integers so that I can use

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

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

to convert the date into time.

将日期转换为时间。

采纳答案by BalusC

That's the hard way, and those java.util.Datesetter methods have been deprecated since Java 1.1 (1997). Simply format the date using SimpleDateFormatusing a format pattern matching the input string.

这是一条艰难的道路,java.util.Date自 Java 1.1 (1997) 以来,那些setter 方法已被弃用。使用SimpleDateFormat与输入字符串匹配的格式模式简单地格式化日期

In your specific case of "January 2, 2010" as the input string:

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

  1. "January" is the full text month, so use the MMMMpattern for it
  2. "2" is the short day-of-month, so use the dpattern for it.
  3. "2010" is the 4-digit year, so use the yyyypattern for it.
  1. “一月”是全文月份,因此请使用该MMMM模式
  2. “2”是一个月中的短日期,因此请使用该d模式。
  3. “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

Note the importance of the explicit Localeargument. If you omit it, then it will use the default localewhich is not necessarily English as used in the month name of the input string. If the locale doesn't match with the input string, then you would confusingly get a java.text.ParseExceptioneven though when the format pattern seems valid.

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

Here's an extract of relevance from the javadoc, listing all available format patterns:

这是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

Note that the patterns are case sensitive and that text based patterns of four characters or more represent the full form; otherwise a short or abbreviated form is used if available. So e.g. MMMMMor more is unnecessary.

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

Here are some examples of valid SimpleDateFormatpatterns to parse a given string to date:

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

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

An important note is that SimpleDateFormatis notthread safe. In other words, you should never declare and assign it as a static or instance variable and then reuse it from different methods/threads. You should always create it brand new within the method local scope.

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



Java 8 update

Java 8 更新

If you happen to be on Java 8 or newer, then use DateTimeFormatter(also here, click the link to see all predefined formatters and available format patterns; the tutorial is available here). This new API is inspired by JodaTime.

如果您碰巧使用的是 Java 8 或更新版本,请使用DateTimeFormatter(也在这里,单击链接查看所有预定义的格式化程序和可用的格式模式;教程在此处可用)。这个新 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

Note: if your format pattern happens to contain the time part as well, then use LocalDateTime#parse(text, formatter)instead of LocalDate#parse(text, formatter). And, if your format pattern happens to contain the time zone as well, then use ZonedDateTime#parse(text, formatter)instead.

注意:如果您的格式模式恰好也包含时间部分,则使用LocalDateTime#parse(text, formatter)代替LocalDate#parse(text, formatter)。而且,如果您的格式模式恰好也包含时区,请ZonedDateTime#parse(text, formatter)改用。

Here's an extract of relevance from the javadoc, listing all available format patterns:

这是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;

Do note that it has several predefined formattersfor the more popular patterns. So instead of e.g. DateTimeFormatter.ofPattern("EEE, d MMM yyyy HH:mm:ss Z", Locale.ENGLISH);, you could use DateTimeFormatter.RFC_1123_DATE_TIME. This is possible because they are, on the contrary to SimpleDateFormat, thread safe. You could thus also define your own, if necessary.

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

For a particular input string format, you don't need to use an explicit DateTimeFormatter: a standard ISO 8601date, like 2016-09-26T17:44:57Z, can be parsed directly with LocalDateTime#parse(text)as it already uses the ISO_LOCAL_DATE_TIMEformatter. Similarly, LocalDate#parse(text)parses an ISO date without the time component (see ISO_LOCAL_DATE), and ZonedDateTime#parse(text)parses an ISO date with an offset and time zone added (see ISO_ZONED_DATE_TIME).

对于特定的输入字符串格式,您不需要使用显式DateTimeFormatter:标准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)。

回答by pn1 dude

Ah yes the Java Date discussion, again. To deal with date manipulation we use Date, Calendar, GregorianCalendar, and SimpleDateFormat. For example using your January date as input:

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

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));

Then you can manipulate that with something like:

然后你可以用类似的东西来操纵它:

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));

回答by Jim

While on dealing with the SimpleDateFormat class, it's important to remember that Date is not thread-safe and you can not share a single Date object with multiple threads.

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

Also there is big difference between "m" and "M" where small case is used for minutes and capital case is used for month. The same with "d" and "D". This can cause subtle bugs which often get overlooked. See Javadocor Guide to Convert String to Date in Javafor more details.

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

回答by Vaishali Kulkarni

Also, SimpleDateFormat is not available with some of the client-side technologies, like GWT.

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

It's a good idea to go for Calendar.getInstance(), and your requirement is to compare two dates; go for long date.

使用 Calendar.getInstance() 是个好主意,您的要求是比较两个日期;去长期约会。

回答by Ruthreshwar

String str_date = "11-June-07";
DateFormat formatter;
Date date;
formatter = new SimpleDateFormat("dd-MMM-yy");
date = formatter.parse(str_date);

回答by Luna Kong

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();
}

It works fine for me.

这对我来说可以。

回答by Basil Bourque

While some of the answers are technically correct, they are not advisable.

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

  • The java.util.Date & Calendar classes are notoriously troublesome. Because of flaws in design and implementation, avoid them. Fortunately we have our choice of two other excellent date-time libraries:
    • Joda-Time
      This popular open-source free-of-cost library can be used across several versions of Java. Many examples of its usage may be found on StackOverflow. Reading some of these will help get you up to speed quickly.
    • java.time.* package
      This new set of classes are inspired by Joda-Time and defined by JSR 310. These classes are built into Java 8. A project is underway to backport these classes to Java 7, but that backporting is not backed by Oracle.
  • As Kristopher Johnson correctly noted in his comment on the question, the other answers ignore vital issues of:
    • Time of Day
      Date has both a date portion and a time-of-day portion)
    • Time Zone
      The beginning of a day depends on the time zone. If you fail to specify a time zone, the JVM's default time zone is applied. That means the behavior of your code may change when run on other computers or with a modified time zone setting. Probably not what you want.
    • Locale
      The Locale's language specifies how to interpret the words (name of month and of day) encountered during parsing. (The answer by BalusChandles this properly.) Also, the Locale affects the output of some formatters when generating a string representation of your date-time.
  • java.util.Date 和 Calendar 类是出了名的麻烦。由于设计和实现中的缺陷,请避免它们。幸运的是,我们可以选择另外两个优秀的日期时间库:
    • Joda-Time
      这个流行的开源免费库可用于多个 Java 版本。在 StackOverflow 上可以找到很多使用它的例子。阅读其中的一些内容将有助于您快速上手。
    • java.time.* package
      这组新类的灵感来自 Joda-Time 并由 JSR 310 定义。这些类内置在 Java 8 中。一个项目正在进行中,将这些类向后移植到 Java 7,但这种向后移植不受甲骨文。
  • 正如克里斯托弗·约翰逊 (Kristopher Johnson) 在对该问题的评论中正确指出的那样,其他答案忽略了以下重要问题:
    • Time of Day
      Date 有日期部分和时间部分)
    • 时区
      一天的开始取决于时区。如果未指定时区,则应用 JVM 的默认时区。这意味着在其他计算机上运行或修改时区设置时,您的代码的行为可能会发生变化。可能不是你想要的。
    • Locale
      Locale 的语言指定如何解释在解析过程中遇到的单词(月份和日期的名称)。(BalusC回答正确处理了这个问题。)此外,在生成日期时间的字符串表示形式时,区域设置会影响某些格式化程序的输出。

Joda-Time

乔达时间

A few notes about Joda-Time follow.

以下是有关 Joda-Time 的一些说明。

Time Zone

时区

In Joda-Time, a DateTimeobject truly knows its own assigned time zone. This contrasts the java.util.Date class which seemsto have a time zone but does not.

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

Note in the example code below how we pass a time zone object to the formatter which parses the string. That time zone is used to interpret that date-time as having occurred in that time zone. So you need to think about and determine the time zone represented by that string input.

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

Since you have no time portion in your input string, Joda-Time assigns the first moment of the day of the specified time zone as the time-of-day. Usually this means 00:00:00but not always, because of Daylight Saving Time (DST)or other anomalies. By the way, you can do the same to any DateTime instance by calling withTimeAtStartOfDay.

由于您的输入字符串中没有时间部分,Joda-Time 将指定时区当天的第一时刻指定为时间。通常这意味着00:00:00但并非总是如此,因为夏令时 (DST)或其他异常情况。顺便说一句,您可以通过调用withTimeAtStartOfDay.

Formatter Pattern

格式化程序模式

The characters used in a formatter's pattern are similar in Joda-Time to those in java.util.Date/Calendar but not exactly the same. Carefully read the doc.

格式化程序模式中使用的字符在 Joda-Time 中类似于 java.util.Date/Calendar 中的字符,但不完全相同。仔细阅读文档。

Immutability

不变性

We usually use the immutable classes in Joda-Time. Rather than modify an existing Date-Time object, we call methods that create a new fresh instance based on the other object with most aspects copied except where alterations were desired. An example is the call to withZonein last line below. Immutabilityhelps to make Joda-Time very thread-safe, and can also make some work more clear.

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

Conversion

转换

You will need java.util.Date objects for use with other classes/framework that do not know about Joda-Time objects. Fortunately, it is very easy to move back and forth.

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

Going from a java.util.Date object (here named date) to Joda-Time DateTime…

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

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

Going the other direction from Joda-Time to a java.util.Date object…

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

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

Sample Code

示例代码

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 ) );

When run…

运行时…

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

回答by micha

With Java 8 we get a new Date / Time API (JSR 310).

在 Java 8 中,我们获得了一个新的日期/时间 API ( JSR 310)。

The following way can be used to parse the date in Java 8 without relying on Joda-Time:

在 Java 8 中可以使用以下方式解析日期,而无需依赖Joda-Time

 String str = "January 2nd, 2010";


// if we 2nd even we have changed in pattern also it is not working please workout with 2nd 
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("MMMM Q, 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


LocalDateis the standard Java 8 class for representing a date (without time). If you want to parse values that contain date and time information you should use LocalDateTime. For values with timezones use ZonedDateTime. Both provide a parse()method similar to LocalDate:

LocalDate是用于表示日期(不含时间)的标准 Java 8 类。如果要解析包含日期和时间信息的值,则应使用LocalDateTime。对于带有时区的值,请使用ZonedDateTime。两者都提供了parse()类似于以下内容的方法LocalDate

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

The list formatting characters from DateTimeFormatter Javadoc:

来自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;

回答by Dimitri Dewaele

My humble test program. I use it to play around with the formatter and look-up long dates that I find in log-files (but who has put them there...).

我不起眼的测试程序。我用它来处理我在日志文件中找到的格式化程序和查找长日期(但谁把它们放在那里......)。

My test program:

我的测试程序:

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);        
        }
    }
}

Test results:

检测结果:

===== 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

回答by siddharth patel

Simple two formatters we have used:

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

  1. Which format date do we want?
  2. Which format date is actually present?
  1. 我们想要哪种格式的日期?
  2. 实际存在哪种格式日期?

We parse the full date to time format:

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

date="2016-05-06 16:40:32";

public static String setDateParsing(String date) throws ParseException {

    // This is the format date we want
    DateFormat mSDF = new SimpleDateFormat("hh:mm a");

    // This format date is actually present
    SimpleDateFormat formatter = new SimpleDateFormat("yyyy-mm-dd hh:mm");
    return mSDF.format(formatter.parse(date));
}