2013-04-22 3 views
1

ПРОБЛЕМА РЕШЕННАЯ Внешнее устройство предназначалось для вычисления и отправки нестандартных 2-х часов сдвинутой метки времени, которые очень смутили меня и начали эту тему. TIMESTAMP BY СЕБЯ НЕ ЗАНЯТОСЬ ОТ ВРЕМЕНИ, временные интервалы применяются только при преобразовании в/из человекообразных форм.Конвертировать временную метку unix между различными часовыми поясами и различными DST в Java


У меня есть метки времени (в секундах от эпохи Unix) в UTC часовой пояс - не DST (летнее время).

Я хочу отметку времени (в секундах от эпохи unix) в часовом поясе «Европа/Прага», который использует DST.

Раньше я думал, что временная метка 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

Что это делает? Что происходит, когда вы распечатываете кал между каждой строкой кода? –

+0

Возможно, вам стоит указать, будете ли вы интересны [Joda-Time] (http: //joda-time.sourceforge.net /), потому что я подозреваю, что вы начнете их получать. –

+0

@Peter для недавней отметки времени «1366642620» она вернула ту же самую - конверсии не произошло. Если я попытаюсь распечатать эту метку времени в PHP в UTC и временах в Европе/Праге, я получаю разное время: 14:57 и 16:57 – David162795

ответ

4

Th ere не является способом «конвертировать» временную метку, это всегда число миллисекунд с эпохи.

Вы можете использовать DateFormat для форматирования метки времени в формате с примененным часовым поясом или использовать календарь, чтобы посмотреть часы, минуты и секунды с примененным часовым поясом.

getTimeInMillis() получает временную метку назад точно так же, как вы поместите его в числе миллисекунд от эпохи: http://docs.oracle.com/javase/1.5.0/docs/api/java/util/Calendar.html#getTimeInMillis%28%29

0

Вы можете легко конвертировать между двумя часовому поясу, как это:

1. Пусть это дата и время в часовом поясе EST

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 из разных часовых поясов. Calendar.setTimeinMilis() ведет себя так, как будто он работает в системном часовом поясе, а не в часовом поясе, заданном в объекте Calendar. – David162795

+0

Как yoy получить фактическую дату вместо строки? –

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, что приводит к разнице почти в 3 часа от utc до местного часового пояса. – xFighter