Java 使用时区将字符串转换为日期
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/4203718/
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
Converting string to date with timezone
提问by John
I have a string in the pattern yyyy-MM-dd hh:mm a and i can get the time zone object separately in which the above string represents the date.
我在模式 yyyy-MM-dd hh:mm a 中有一个字符串,我可以分别获取时区对象,其中上述字符串表示日期。
I want to convert this to the below format. yyyy-MM-dd HH:mm:ss Z
我想将其转换为以下格式。yyyy-MM-dd HH:mm:ss Z
How can i do this?
我怎样才能做到这一点?
回答by Jigar Joshi
Use SimpleDateFormat
String string1 = "2009-10-10 12:12:12 ";
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss Z")
sdf.setTimeZone(tz);
Date date = sdf.parse(string1);
回答by Robert
Create a new instance of SimpleDateFormatusing your date pattern. Afterwards you can call it's parse method to convert date strings to a java.util.Dateobject.
使用您的日期模式创建SimpleDateFormat的新实例。之后,您可以调用它的 parse 方法将日期字符串转换为java.util.Date对象。
回答by Michael Konietzka
You can use SimpleDateFormatwith yyyy-MM-dd HH:mm:ss
and explicitly set the TimeZone:
您可以使用的SimpleDateFormat使用yyyy-MM-dd HH:mm:ss
,并明确设置时区:
public static Date getSomeDate(final String str, final TimeZone tz)
throws ParseException {
final SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd hh:mm a");
sdf.setTimeZone(tz);
return sdf.parse(str);
}
/**
* @param args
* @throws IOException
* @throws InterruptedException
* @throws ParseException
*/
public static void main(final String[] args) throws ParseException {
final SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss Z");
System.out.println(sdf.format(getSomeDate(
"2010-11-17 01:12 pm", TimeZone.getTimeZone("Europe/Berlin"))));
System.out.println(sdf.format(getSomeDate(
"2010-11-17 01:12 pm", TimeZone.getTimeZone("America/Chicago"))));
}
Prints out:
打印出来:
2010-11-17 13:12:00 +0100
2010-11-17 20:12:00 +0100
2010-11-17 13:12:00 +0100
2010-11-17 20:12:00 +0100
Update 2010-12-01:If you want to explicitly printout a special TimeZone, set it in the SimpleDateFormat:
2010 年 12 月 1 日更新:如果您想明确打印出一个特殊的时区,请在 SimpleDateFormat 中设置它:
sdf.setTimeZone(TimeZone .getTimeZone("IST"));
System.out.println(sdf.format(getSomeDate(
"2010-11-17 01:12 pm", TimeZone.getTimeZone("IST"))));
Which prints 2010-11-17 13:12:00 +0530
哪个打印 2010-11-17 13:12:00 +0530
回答by Somum
Undoubtedly, the format which is generally used will be of a form 2014-10-05T15:23:01Z
(TZ)
毫无疑问,通常使用的格式将是一种形式2014-10-05T15:23:01Z
(TZ)
For that one has to use this code
为此必须使用此代码
SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ssZ");
String dateInString = "2014-10-05T15:23:01Z";
try {
Date date = formatter.parse(dateInString.replaceAll("Z$", "+0000"));
System.out.println(date);
} catch (ParseException e) {
e.printStackTrace();
}
Its output will be Sun Oct 05 20:53:01 IST 2014
它的输出将是 Sun Oct 05 20:53:01 IST 2014
However, I am not sure why we had to replaceAll "Z" if you do not add replaceAll the program will fail.
但是,我不确定为什么我们必须要 replaceAll "Z" 如果不添加 replaceAll 程序会失败。
回答by Basil Bourque
tl;dr
tl;博士
LocalDateTime.parse( // Parse string as value without time zone and without offset-from-UTC.
"2017-01-23 12:34 PM" ,
DateTimeFormatter.ofPattern( "uuuu-MM-dd hh:mm a" )
) // Returns a `LocalDateTime` object.
.atZone( ZoneId.of( "America/Montreal" ) ) // Assign time zone, to determine a moment. Returns a `ZonedDateTime` object.
.toInstant() // Adjusts from zone to UTC.
.toString() // Generate string: 2017-01-23T17:34:00Z
.replace( "T" , " " ) // Substitute SPACE for 'T' in middle.
.replace( "Z" , " Z" ) // Insert SPACE before 'Z'.
Avoid legacy date-time classes
避免遗留的日期时间类
The other Answers use the troublesome old date-time classes (Date
, Calendar
, etc.), now legacy, supplanted by the java.time classes.
其他答案使用麻烦的旧日期时间类(Date
,Calendar
,等),现在的传统,由java.time类取代。
LocalDateTime
LocalDateTime
I have a string in the pattern yyyy-MM-dd hh:mm a
我在模式 yyyy-MM-dd hh:mm a 中有一个字符串
Such an input string lacks any indication of offset-from-UTC or time zone. So we parse as a LocalDateTime
.
这样的输入字符串没有任何从 UTC 或时区偏移的指示。所以我们解析为LocalDateTime
.
Define a formatting pattern to match your input with a DateTimeFormatter
object.
定义格式模式以将您的输入与DateTimeFormatter
对象相匹配。
String input = "2017-01-23 12:34 PM" ;
DateTimeFormatter f = DateTimeFormatter.ofPattern( "uuuu-MM-dd hh:mm a" );
LocalDateTime ldt = LocalDateTime.parse( input , f );
ldt.toString(): 2017-01-23T12:34
ldt.toString(): 2017-01-23T12:34
Note that a LocalDateTime
is nota specific moment, only a vague idea about a range of possible moments. For example, a few minutes after midnight in Paris France is still “yesterday” in Montréal Canada. So without the context of a time zone such as Europe/Paris
or America/Montreal
, just saying “a few minutes after midnight” has no meaning.
请注意,LocalDateTime
是不是一个特定的时刻,只有各种可能的时刻,一个模糊的概念。例如,法国巴黎午夜过后几分钟在加拿大蒙特利尔仍然是“昨天”。因此,如果没有时区的上下文,例如Europe/Paris
or America/Montreal
,仅仅说“午夜后的几分钟”是没有意义的。
ZoneId
ZoneId
and i can get the time zone object separately in which the above string represents the date.
我可以分别获取时区对象,其中上述字符串表示日期。
A time zone is represented by the ZoneId
class.
时区由ZoneId
类表示。
Specify a proper time zone namein the format of continent/region
, such as America/Montreal
, Africa/Casablanca
, or Pacific/Auckland
. Never use the 3-4 letter abbreviation such as EST
or IST
as they are nottrue time zones, not standardized, and not even unique(!).
以、、 或等格式指定正确的时区名称。永远不要使用 3-4 个字母的缩写,例如或因为它们不是真正的时区,不是标准化的,甚至不是唯一的(!)。continent/region
America/Montreal
Africa/Casablanca
Pacific/Auckland
EST
IST
ZoneId z = ZoneId.of( "America/Montreal" );
ZonedDateTime
ZonedDateTime
Apply the ZoneId
to get a ZonedDateTime
which is indeed a point on the timeline, a specific moment in history.
应用ZoneId
得到 aZonedDateTime
这确实是时间轴上的一个点,历史上的一个特定时刻。
ZonedDateTime zdt = ldt.atZone( z );
zdt.toString(): 2017-01-23T12:34-05:00[America/Montreal]
zdt.toString(): 2017-01-23T12:34-05:00[美国/蒙特利尔]
Instant
Instant
I want to convert this to the below format. yyyy-MM-dd HH:mm:ss Z
我想将其转换为以下格式。yyyy-MM-dd HH:mm:ss Z
First, know that a Z
literal character is short for Zulu
and means UTC. In other words, an offset-from-UTCof zero hours, +00:00
.
首先,要知道Z
文字字符是UTC 的缩写Zulu
,表示UTC。换句话说,零小时的 UTC 偏移量+00:00
。
The Instant
class represents a moment on the timeline in UTCwith a resolution of nanoseconds(up to nine (9) digits of a decimal fraction).
该Instant
级表示时间轴上的时刻UTC,分辨率为纳秒(最多小数的9个位数)。
You can extract a Instant
object from a ZonedDateTime
.
您可以Instant
从ZonedDateTime
.
Instant instant = zdt.toInstant(); // Extracting the same moment but in UTC.
To generate a string in standard ISO 8601format, such as 2017-01-22T18:21:13.354Z
, call toString
. The standard format has no spaces, uses a T
to separate the year-month-date from the hour-minute-second, and appends the Z
canonically for an offset of zero.
要生成标准ISO 8601格式的字符串,例如2017-01-22T18:21:13.354Z
,请调用toString
. 标准格式没有空格,使用 aT
将年-月-日与时-分-秒分开,并将Z
规范附加为零偏移量。
String output = instant.toString();
instant.toString(): 2017-01-23T17:34:00Z
Instant.toString(): 2017-01-23T17:34:00Z
I strongly suggest using the standard formats whenever possible. If you insist on using spaces as in your stated desired format, either define your own formatting pattern in a DateTimeFormatter
object or just do a string manipulation on the output of Instant::toString
.
我强烈建议尽可能使用标准格式。如果您坚持按照您声明的所需格式使用空格,请在DateTimeFormatter
对象中定义您自己的格式模式,或者只是对Instant::toString
.
String output = instant.toString()
.replace( "T" , " " ) // Substitute SPACE for T.
.replace( "Z" , " Z" ); // Insert SPACE before Z.
output: 2017-01-23 17:34:00 Z
输出:2017-01-23 17:34:00 Z
Try this code live at IdeOne.com.
About java.time
关于 java.time
The java.timeframework is built into Java 8 and later. These classes supplant the troublesome old legacydate-time classes such as java.util.Date
, Calendar
, & SimpleDateFormat
.
该java.time框架是建立在Java 8和更高版本。这些类取代了麻烦的旧的遗留日期时间类,例如java.util.Date
, Calendar
, & SimpleDateFormat
。
The Joda-Timeproject, now in maintenance mode, advises migration to the java.timeclasses.
现在处于维护模式的Joda-Time项目建议迁移到java.time类。
To learn more, see the Oracle Tutorial. And search Stack Overflow for many examples and explanations. Specification is JSR 310.
要了解更多信息,请参阅Oracle 教程。并在 Stack Overflow 上搜索许多示例和解释。规范是JSR 310。
Where to obtain the java.time classes?
从哪里获得 java.time 类?
- Java SE 8and SE 9and later
- Built-in.
- Part of the standard Java API with a bundled implementation.
- Java 9 adds some minor features and fixes.
- Java SE 6and SE 7
- Much of the java.time functionality is back-ported to Java 6 & 7 in ThreeTen-Backport.
- Android
- The ThreeTenABPproject adapts ThreeTen-Backport(mentioned above) for Android specifically.
- See How to use ThreeTenABP….
- Java SE 8和SE 9及更高版本
- 内置。
- 具有捆绑实现的标准 Java API 的一部分。
- Java 9 添加了一些小功能和修复。
- Java SE 6和SE 7
- 多的java.time功能后移植到Java 6和7在ThreeTen-反向移植。
- 安卓
- 所述ThreeTenABP项目适应ThreeTen-反向移植(上述)为Android特异性。
- 请参阅如何使用ThreeTenABP ...。
The ThreeTen-Extraproject extends java.time with additional classes. This project is a proving ground for possible future additions to java.time. You may find some useful classes here such as Interval
, YearWeek
, YearQuarter
, and more.
该ThreeTen-额外项目与其他类扩展java.time。该项目是未来可能添加到 java.time 的试验场。你可能在这里找到一些有用的类,比如Interval
,YearWeek
,YearQuarter
,和更多。