2010-11-17 34 views
9

我有一个模式yyyy-MM-dd hh:mm a 中的字符串,我可以分别获取上述字符串表示日期的时区对象。将字符串转换为带时区日期

我想将其转换为以下格式。 yyyy-MM-dd HH:mm:ss Z

我该怎么做?

+0

http://joda-time.sourceforge.net/使所有日期的操作在java中多容易得多 – NimChimpsky 2010-11-17 11:09:52

+0

@Emil我才知道这个功能你说:),谢谢了。 – John 2010-11-17 11:41:33

+1

FYI时,[乔达-时间](http://www.joda.org/joda-time/)项目现在在[维护模式](https://en.wikipedia.org/wiki/Maintenance_mode)中,用该团队建议迁移到[java.time](http://docs.oracle.com/javase/8/docs/api/java/time/package-summary.html)类。 – 2017-01-22 21:47:14

回答

5

使用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); 
+0

某些时候,getID()返回像这样的字符串“America/Argentina/Ushuaia”。那么我怎样才能使用它 – John 2010-11-17 11:42:09

+0

-1:这将在大多数时区抛出ParseException。 – 2010-11-17 12:51:16

+0

@迈克尔Konietzka @shal我赶紧我错过了,更新了答案 – 2010-11-17 12:59:41

0

使用日期模式创建的SimpleDateFormat一个新的实例。之后,您可以将其称为解析方法,以将日期字符串转换为java.util.Date对象。

16

您可以使用SimpleDateFormatyyyy-MM-dd HH:mm:ss并明确设置TimeZone

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

打印出:

2010-11-17十三时12分00秒+0100

2010- 11-17 20:12:00 +0100

更新2010-12-01: 如果你想明确地印出特殊的时区,将其设置在SimpleDateFormat的:

sdf.setTimeZone(TimeZone .getTimeZone("IST")); 
System.out.println(sdf.format(getSomeDate(
    "2010-11-17 01:12 pm", TimeZone.getTimeZone("IST")))); 

它打印2010-11-17 13:12:00 +0530

+0

由于内容Mr.michael,日期和时间根据Timezone.Note下来+100得到改变,它不会改变区偏移 – John 2010-11-18 11:37:39

+0

@shal :对不起,我不明白你的第二句话。你认为有什么不对吗? – 2010-11-18 11:55:56

+0

@迈克尔,我说的时间也越来越正确转换,但看到日期值的“Z”部分印有“+0100”如果我从GMT转换日期IST那么“不changes.For如Z“部分的转换日期必须为”+0530“。 – John 2010-12-01 10:24:57

0

毫无疑问,这是通常使用的格式是一个形式2014-10-05T15:23:01Z(TZ)

对于一个具有使用此代码

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

它的输出将是太阳10月05日20:53:01 IST 2014

然而,我不知道为什么我们必须替换所有“Z”,如果你不添加replaceAll程序将失败。

4

TL;博士

LocalDateTime.parse( // Parse string as value without time zone. 
    "2017-01-23 12:34 PM" , 
    DateTimeFormatter.ofPattern("uuuu-MM-dd hh:mm a") 
).atZone(ZoneId.of("America/Montreal")) // Assign time zone. 
.toString()    // Generate string: 2017-01-23T17:34:00Z 
.replace("T" , " ") // Substitute SPACE for 'T' in middle. 
.replace("Z" , " Z") // Insert SPACE before 'Z'. 

避免遗留日期时类

其他答案使用麻烦的旧日期时类(DateCalendar等),现在的传统,由取代java.time类。

LocalDateTime

我在图案YYYY-MM-DD HH的字符串:毫米

这样的输入字符串缺少的任何指示偏移从-UTC或时区。所以我们解析为LocalDateTime

定义一个格式模式,以便将您的输入与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

注意,一个LocalDateTime特定时刻,只有各种可能的时刻,一个模糊的概念。例如,巴黎午夜过后几分钟,法国在加拿大蒙特利尔仍然是“昨天”。因此,如果没有时区的上下文,例如Europe/ParisAmerica/Montreal,只是说“午夜后几分钟”没有意义。

ZoneId

和我可以得到单独的时区对象,其中上面的字符串表示的日期。

时区由ZoneId类表示。

continent/region的格式指定一个proper time zone name,如America/MontrealAfrica/Casablanca,或Pacific/Auckland。切勿使用3-4字母缩写,如ESTIST,因为它们是而不是真正的时区,不是标准化的,甚至不是唯一的(!)。

ZoneId z = ZoneId.of("America/Montreal"); 

ZonedDateTime

应用ZoneId获得ZonedDateTime这的确是时间轴,在历史上的一个特定的时刻上的一个点。

ZonedDateTime zdt = ldt.atZone(z); 

zdt.toString():2017-01-23T12:34-05:00 [美国/蒙特利尔]

Instant

我想将其转换为下面的格式。 YYYY-MM-DD HH:MM:SSž

首先,知道一个Z文字字符是短期的和Zulu装置UTC。换句话说,零小时的offset-from-UTC+00:00

Instant类表示UTCnanoseconds(最多9个(9)小数的位数)的分辨率在时间轴上的力矩。

您可以从ZonedDateTime中提取Instant对象。

Instant instant = zdt.toInstant(); // Extracting the same moment but in UTC. 

为了产生在标准ISO 8601格式的字符串,如2017-01-22T18:21:13.354Z,呼叫toString。标准格式没有空格,使用T将year-month-date与hour-minute-second分开,并将Z附加为零的偏移量。

String output = instant.toString(); 

instant.toString():2017-01-23T17:34:00Z

我强烈建议使用标准的格式只要有可能。如果您坚持使用所需格式的空格,请在DateTimeFormatter对象中定义您自己的格式模式,或者仅对Instant::toString的输出执行字符串操作。

String output = instant.toString() 
         .replace("T" , " ") // Substitute SPACE for T. 
         .replace("Z" , " Z"); // Insert SPACE before Z. 

输出:

2017年1月23日17点34分00秒ž试试这个code live at IdeOne.com


关于java.time

java.time框架是建立在Java 8和更高版本。这些类取代了日期时间类legacy,如java.util.Date,Calendar,& SimpleDateFormat

Joda-Time项目现在位于maintenance mode,建议迁移到java.time类。请参阅Oracle Tutorial。并搜索堆栈溢出了很多例子和解释。规格是JSR 310

从何处获取java.time类?

ThreeTen-Extra项目与其他类扩展java.time。这个项目是未来可能增加java.time的一个试验场。您可以在这里找到一些有用的类,如Interval,YearWeek,YearQuartermore