2013-04-22 120 views
1

问题已解决外部设备正在计算和发送非标准的2小时移位时间戳,这非常困惑我并启动了此线程。 TIMESTAMP本身不受时区,时区从人类可读形式/转换只有当适用。在Java中的不同时区和不同DST之间转换unix时间戳


我在UTC时区的时间戳(自Unix纪元秒) - 没有DST(夏令时间)。

我想在“欧洲/布拉格”时区,使用DST时间戳(自Unix纪元秒)。

我曾经认为Unix时间戳是由未结合的时区,该时区只影响转换时间戳人类可读的格式的过程。但看起来不是这样。而我试图转换它(使用Calendar和TimeZone类)越多,我越感到困惑和迷茫。

预期验证码不起作用:

Calendar cal = GregorianCalendar.getInstance(TimeZone.getTimeZone("UTC")); 
cal.setTimeInMillis(ts*1000); 
cal.setTimeZone(TimeZone.getTimeZone("Europe/Prague")); 
return cal.getTimeInMillis()/1000; 
+0

这是什么呢?在每行代码之间打印cal时会发生什么? – 2013-04-22 13:23:30

+0

你或许应该说明你是否会有兴趣在[乔达时间(HTTP://joda-time.sourceforge。网/)解决方案,因为我怀疑你会开始接收它们。 – 2013-04-22 13:24:53

+0

@Peter最近的时间戳'1366642620'它返回了同一个 - 没有转换发生。如果我尝试在UTC和欧洲/布拉格时区打印出PHP中的时间戳,我会得到不同的时间:14:57和16:57 – David162795 2013-04-22 13:40:16

回答

0

您可以方便地在两个时区之间的转换是这样的:

1.Suppose这是在美国东部时区的日期和时间

String value = "2006-11-28 09:45:12"; 
DateFormat df1 = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); 
df1.setTimeZone(TimeZone.getTimeZone("EST")); 

2.设定该值,并假设它代表EST时区中的日期和时间

Date d = df1.parse(value);  
DateFormat df2 = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); 
df2.setTimeZone(TimeZone.getTimeZone("CET")); 

3.Formats在CET时区的日期

System.out.println(df2.format(d)); 
+0

我见过类似的例子,但它的输入格式是(小时,分钟,秒),而不是unix时间戳。我的问题是我不知道如何从不同的时区加载'unix timestamp'。 Calendar.setTimeinMilis()的行为就好像它在系统时区中工作,而不是在Calendar对象中设置的时区。 – David162795 2013-04-22 13:34:39

+0

如何获得实际日期而不是字符串? – 2016-05-02 20:06:03

0

它的行为我希望

public static void main(String... ignored) { 
    long ts = System.currentTimeMillis()/1000; 
    Calendar cal = GregorianCalendar.getInstance(TimeZone.getTimeZone("UTC")); 
    printCalendar(cal); 
    cal.setTimeInMillis(ts * 1000); 
    printCalendar(cal); 
    cal.setTimeZone(TimeZone.getTimeZone("Europe/Prague")); 
    printCalendar(cal); 
} 

public static void printCalendar(Calendar calendar) { 
    SimpleDateFormat sdf = new SimpleDateFormat("yyyy/MM/dd HH:mm:ss.SSS ZZZ"); 
    sdf.setTimeZone(calendar.getTimeZone()); 
    System.out.println(sdf.format(calendar.getTime())); 
} 

打印

2013/04/22 13:28:06.451 +0000 
2013/04/22 13:28:06.000 +0000 
2013/04/22 15:28:06.000 +0200 
2

这里是一个示例代码转换时期时区之间。

public static long convertTimeZone(long lngDate, String fromTimeZone, 
     String toTimeZone) {   
    Calendar fromTime = Calendar.getInstance(); 
    fromTime.setTimeZone(TimeZone.getTimeZone(fromTimeZone)); 
    fromTime.setTimeInMillis(lngDate); 
    Calendar toTime = new GregorianCalendar(
      TimeZone.getTimeZone(toTimeZone)); 
    toTime.set(Calendar.DATE, fromTime.get(Calendar.DATE)); 
    toTime.set(Calendar.MONTH, fromTime.get(Calendar.MONTH)); 
    toTime.set(Calendar.YEAR, fromTime.get(Calendar.YEAR)); 
    toTime.set(Calendar.HOUR_OF_DAY, fromTime.get(Calendar.HOUR_OF_DAY)); 
    toTime.set(Calendar.MINUTE, fromTime.get(Calendar.MINUTE)); 
    toTime.set(Calendar.SECOND, fromTime.get(Calendar.SECOND)); 
    toTime.set(Calendar.MILLISECOND, fromTime.get(Calendar.MILLISECOND)); 
    LOG.debug("Converted " + fromTime.getTimeInMillis() + " to " 
      + toTime.getTimeInMillis()); 
    SimpleDateFormat sdf = new SimpleDateFormat(
      "dd-MMM-yyyy HH:mm:ss.SSS z");  
    sdf.setTimeZone(TimeZone.getTimeZone(fromTimeZone));   
    SimpleDateFormat sdf1 = new SimpleDateFormat(
      "dd-MMM-yyyy HH:mm:ss.SSS z");  
    sdf1.setTimeZone(TimeZone.getTimeZone(toTimeZone)); 
    LOG.debug("Converted " + sdf.format(fromTime.getTime()) + " to " + sdf1.format(toTime.getTime())); 
    return toTime.getTimeInMillis(); 
} 

输出:

System.out.println(convertTimeZone(new Date().getTime(),"America/New_York","Asia/Singapore")); 
Converted 1384514879944 to 1384468079944 
Converted 15-Nov-2013 06:27:59.944 EST to 15-Nov-2013 06:27:59.944 SGT 
+0

我已经做了4个多小时。我终于得到了正确的结果。它似乎是java中的一个错误,或者是您添加的行,它会将毫秒添加到toTime对象,从而导致从utc到本地时区差不多3个小时。 – xFighter 2016-12-14 18:04:04