2012-06-29 31 views
3

我有下面的代码:Java时区 - 与IST的奇怪行为?

DateFormat df = new SimpleDateFormat("M/d/yy h:mm a z"); 
df.setLenient(false); 
System.out.println(df.parse("6/29/2012 5:15 PM IST")); 

假设我现在我的电脑的时区设置为太平洋时间(UTC-7 PDT),这个打印

周五6月29日8点15分00秒PDT 2012

是不是PDT比IST(印度标准时间)少12.5小时?这个问题不会发生在任何其他时区 - 我在日期字符串中尝试了UTC,PKT,MMT等而不是IST。 Java中有两个IST有可能吗?

P.S:实际代码中的日期字符串来自外部源,所以我不能使用GMT偏移量或任何其他时区格式。

+0

据我所知,有几个IST。根据时差(9小时)判断,你可能已经获得了以色列标准时间。 – biziclop

+0

@biziclop我想过这个。但是,让我远离的是: 'System.out.println(TimeZone.getTimeZone(“IST”)。getRawOffset());' 这打印19800000或5.5小时,这表明它确实是印度人标准时间。或者它是否捡起了具有相同ID“IST”的许多时区中的第一个?如果是这样,如果某件事物在许多事情上都是相同的,又怎么能成为“身份证”呢? – Vasan

+0

@esej这更可能是时区缩写中的一个模棱两可的问题:http://en.wikipedia.org/wiki/List_of_time_zone_abbreviations – biziclop

回答

5

对不起,我必须写这个答案,但试试这个代码:

public class Test { 

    public static void main(String[] args) throws ParseException { 
     DF df = new DF("M/d/yy h:mm a z"); 
     String [][] zs = df.getDateFormatSymbols().getZoneStrings(); 
     for(String [] z : zs) { 
      System.out.println(Arrays.toString(z)); 
     } 
    } 

    private static class DF extends SimpleDateFormat { 
     @Override 
     public DateFormatSymbols getDateFormatSymbols() { 
      return super.getDateFormatSymbols(); 
     } 

     public DF(String pattern) { 
      super(pattern); 
     } 
    } 

} 

你会发现,IST多次出现在列表中,第一个是确实以色列标准时间。

+1

谢谢,这很有帮助。那么我想我必须做一些奇怪的事情,比如在解析它之前从日期字符串中剥离时区。然后我可以将时区部分传递给TimeZone.getTimeZone()以获取实际时区(我想即使这样也不能保证始终工作!)。它现在都变得不完整了,该死的你DateFormat! – Vasan

+0

@Vasan那么,DateFormat不是这里唯一的罪魁祸首,基本问题是时区缩写词不是唯一的。事后看来,这是一个愚蠢的想法。 :) – biziclop

3

不是一个答案,但看到输出+代码如下 - 它似乎是parse对待来自TimeZone.getTimeZone("IST") IST不同...

周五06月29日16:15:00 BST 2012
周五12年6月29日:45:00 BST 2012
周五6月29日12时45分〇〇秒BST 2012
* BST =伦敦

public static void main(String[] args) throws InterruptedException, ParseException { 
    DateFormat fmt1 = new SimpleDateFormat("M/d/yy h:mm a Z"); 
    Date date = fmt1.parse("6/29/2012 5:15 PM IST"); 
    System.out.println(date); 

    DateFormat fmt2 = new SimpleDateFormat("M/d/yy h:mm a"); 
    fmt2.setTimeZone(TimeZone.getTimeZone("IST")); 
    System.out.println(fmt2.parse("6/29/2012 5:15 PM")); 

    DateFormat fmt3 = new SimpleDateFormat("M/d/yy h:mm a"); 
    fmt3.setTimeZone(TimeZone.getTimeZone("Asia/Kolkata")); 
    System.out.println(fmt3.parse("6/29/2012 5:15 PM")); 
} 
+0

是的,这正是我所说的。 'SimpleDateFormat'是一个奇怪的野兽,并不遵守规则。它有自己的时区数据数组,并使用其中的任何内容。 – biziclop

9

时区的绰号名称是不明确的,并且对于时区的奥尔森名称已被弃用。以下工作一致,因为parse()和getTimezone()的行为方式可能有所不同。

SimpleDateFormat sdf = new SimpleDateFormat("M/d/yy h:mm a Z"); 
TimeZone istTimeZone = TimeZone.getTimeZone("Asia/Kolkata"); 
Date d = new Date(); 
sdf.setTimeZone(istTimeZone); 
String strtime = sdf.format(d);