Преобразование даты/времени для данного часового пояса - java - программирование
Подтвердить что ты не робот

Преобразование даты/времени для данного часового пояса - java

Я хочу преобразовать эту отметку времени GMT в GMT + 13:

2011-10-06 03:35:05

Я попробовал около 100 различных комбинаций DateFormat, TimeZone, Date, GregorianCalendar и т.д., чтобы попытаться сделать это ОЧЕНЬ основную задачу.

Этот код делает то, что я хочу для ТЕКУЩЕГО ВРЕМЕНИ:

Calendar calendar = new GregorianCalendar(TimeZone.getTimeZone("GMT"));

DateFormat formatter = new SimpleDateFormat("dd MMM yyyy HH:mm:ss z");    
formatter.setTimeZone(TimeZone.getTimeZone("GMT+13"));  

String newZealandTime = formatter.format(calendar.getTime());

Но я хочу установить время, а не использовать текущее время.

Я обнаружил, что в любое время я пытаюсь установить такое время:

calendar.setTime(new Date(1317816735000L));

используется локальная машина TimeZone. Почему это? Я знаю, что когда "new Date()" возвращает UTC + 0, почему, когда вы устанавливаете Time в миллисекундах, больше не предполагается, что время в UTC?

Возможно:

  • Задайте время для объекта (Календарь/Дата/Время)
  • (возможно) Установите временной интервал начальной отметки времени (calendar.setTimeZone(...))
  • Отметьте метку времени новым TimeZone (formatter.setTimeZone(...)))
  • Возвращает строку с новым часовым поясом. (Formatter.format(calendar.getTime()))

Заранее благодарим за помощь: D

4b9b3361

Ответ 1

Для меня самый простой способ сделать это:

Calendar calendar = Calendar.getInstance();
calendar.setTime(new Date());
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss");

//Here you say to java the initial timezone. This is the secret
sdf.setTimeZone(TimeZone.getTimeZone("UTC"));
//Will print in UTC
System.out.println(sdf.format(calendar.getTime()));    

//Here you set to your timezone
sdf.setTimeZone(TimeZone.getDefault());
//Will print on your default Timezone
System.out.println(sdf.format(calendar.getTime()));

Ответ 2

Понимание того, как работает компьютерное время, очень важно. С учетом сказанного я согласен, что если API создан, чтобы помочь вам обрабатывать компьютерное время, как в реальном времени, тогда он должен работать таким образом, чтобы вы могли рассматривать его как в реальном времени. По большей части это так, но есть некоторые основные недочеты, которые требуют внимания.

В любом случае я отвлекаюсь! Если у вас есть UTC смещение (лучше работать в UTC, чем GMT смещения), вы можете рассчитать время в миллисекундах и добавить его в метку времени. Обратите внимание, что временная метка SQL может отличаться от временной метки Java, так как способ вычисления времени перехода от эпохи не всегда одинаков - зависит от технологий баз данных, а также от операционных систем.

Я бы посоветовал использовать System.currentTimeMillis() в качестве ваших штампов времени, поскольку их можно более последовательно обрабатывать в java, не беспокоясь о преобразовании меток времени SQL в объекты java Date и т.д.

Чтобы рассчитать смещение, вы можете попробовать что-то вроде этого:

Long gmtTime =1317951113613L; // 2.32pm NZDT
Long timezoneAlteredTime = 0L;

if (offset != 0L) {
    int multiplier = (offset*60)*(60*1000);
    timezoneAlteredTime = gmtTime + multiplier;
} else {
    timezoneAlteredTime = gmtTime;
}

Calendar calendar = new GregorianCalendar();
calendar.setTimeInMillis(timezoneAlteredTime);

DateFormat formatter = new SimpleDateFormat("dd MMM yyyy HH:mm:ss z");

formatter.setCalendar(calendar);
formatter.setTimeZone(TimeZone.getTimeZone(timeZone));

String newZealandTime = formatter.format(calendar.getTime());

Я надеюсь, что это будет полезно!

Ответ 3

Как всегда, я рекомендую читать эту статью о дате и времени на Java, чтобы вы это поняли.

Основная идея заключается в том, что "под капотом" все делается в UTC миллисекундах с эпохи. Это означает, что это проще всего, если вы работаете без использования часовых поясов вообще, за исключением форматирования строки для пользователя.

Поэтому я пропустил бы большинство шагов, которые вы предложили.

  • Задайте время для объекта (дата, календарь и т.д.).
  • Установите часовой пояс для объекта форматирования.
  • Возвращает строку из форматирования.

В качестве альтернативы вы можете использовать Joda time. Я слышал, что это гораздо более интуитивный API datetime.

Ответ 4

ТЛ; др

Instant.ofEpochMilli( 1_317_816_735_000L )
    .atZone( ZoneId.of( "Pacific/Auckland" ) )
    .format( DateTimeFormatter.ofLocalizedDateTime( FormatStyle.MEDIUM ).withLocale( new Locale( "en" , "NZ" ) ) )

…также…

LocalDateTime.parse( "2011-10-06 03:35:05".replace( " " , "T" ) )
    .atZone( ZoneId.of( "Pacific/Auckland" ) )

java.time

В Вопросе и большинстве Ответов используются устаревшие классы даты и времени из самых ранних версий Java. Эти старые классы оказались неприятными и запутанными. Избежать их. Вместо этого используйте классы java.time.

ISO 8601

Ваша входная строка почти в стандартном формате ISO 8601. Просто замените ПРОБЕЛ в середине буквой T

String input = "2011-10-06 03:35:05".replace( " " , "T" );

LocalDateTime

Теперь проанализируйте как LocalDateTime потому что на входе отсутствует какая-либо информация о смещении от UTC или часовом поясе. LocalDateTime не имеет понятия смещения или часового пояса, поэтому он не представляет фактический момент на временной шкале.

LocalDateTime ldt = LocalDateTime.parse( input );

ZoneOffset

Похоже, вы говорите, что из бизнес-контекста вы знаете, что эта строка предназначена для представления момента, который на 13 часов опережает UTC. Итак, мы создаем экземпляр ZoneOffset.

ZoneOffset offset = ZoneOffset.ofHours( 13 ); // 13 hours ahead of UTC, in the far east of the globe.

OffsetDateTime

Примените его, чтобы получить объект OffsetDateTime. Это становится актуальным моментом времени.

OffsetDateTime odt = ldt.atOffset( offset);

ZoneId

Но тогда вы упоминаете Новую Зеландию. Таким образом, вы имели в виду определенный часовой пояс. Часовой пояс - это смещение от UTC плюс набор правил для обработки аномалий, таких как переход на летнее время (DST). Таким образом, мы можем указать ZoneId для ZonedDateTime а не просто смещение.

Укажите правильное имя часового пояса. Никогда не используйте 3-4-буквенное сокращение, такое как EST или IST поскольку они не являются истинными часовыми поясами, не стандартизированы и даже не уникальны (!). Например, Pacific/Auckland.

ZoneId z = ZoneId.of( "Pacific/Auckland" );

ZonedDateTime

Примените ZoneId.

ZonedDateTime zdt = ldt.atZone( z );

Вы можете легко перейти в другую зону в тот же момент на временной шкале.

ZoneId zParis = ZoneId.of( "Europe/Paris" );
ZonedDateTime zdtParis = zdt.withZoneSameInstant( zParis );  // Same moment in time, but seen through lens of Paris wall-clock time.

Считать с эпохи

Я настоятельно рекомендую не обрабатывать значения даты и времени в виде отсчета от эпохи, например, миллисекунд с начала 1970 UTC. Но если нужно, создайте Instant из такого числа.

Instant instant = Instant.ofEpochMilli( 1_317_816_735_000L );

Затем назначьте часовой пояс, как показано выше, если хотите, чтобы отойти от UTC.

ZoneId z = ZoneId.of( "Pacific/Auckland" );
ZonedDateTime zdt = instant.atZone( z );

Ваше значение 1_317_816_735_000L:

  • 2011-10-05T12:12:15Z (среда, 05 октября 2011 года, 12:12:15 по Гринвичу)
  • 2011-10-06T01:12:15+13:00[Pacific/Auckland] (четверг, 6 октября 2011 года, 01:12:15 в Окленде, Новая Зеландия).

Генерировать строки

Чтобы сгенерировать строку в стандартном формате ISO 8601, просто вызовите toString. Обратите внимание, что ZonedDateTime разумно расширяет стандартный формат, добавляя имя часового пояса в квадратных скобках.

String output = zdt.toString();

Для других форматов выполните поиск для класса DateTimeFormatter. Уже покрыто много раз.

Укажите FormatStyle и Locale.

Locale l = new Locale( "en" , "NZ" );
DateTimeFormatter f = DateTimeFormatter.ofLocalizedDateTime( FormatStyle.MEDIUM ).withLocale( l );
String output = zdt.format( f );

Обратите внимание, что часовой пояс не имеет ничего общего с локалью. Вы можете отображать дату/время в Europe/Paris на японском языке и культурные нормы, или дату на Asia/Kolkata на португальском языке и культурные нормы Бразилии.

О java.time

Инфраструктура java.time встроена в Java 8 и более поздние версии. Эти классы вытеснять неприятные старые классы даты и времени, такие как java.util.Date, .Calendar, и java.text.SimpleDateFormat.

Проект Joda-Time, находящийся сейчас в режиме обслуживания, рекомендует перейти на java.time.

Чтобы узнать больше, смотрите Oracle Tutorial. И поиск для многих примеров и объяснений.

Большая часть функциональности java.time перенесена на Java 6 и 7 в ThreeTen-Backport и дополнительно адаптирована для Android в ThreeTenABP (см. Как использовать…).

Проект ThreeTen-Extra расширяет java.time дополнительными классами. Этот проект является полигоном для возможных будущих дополнений к java.time. Здесь вы можете найти некоторые полезные классы, такие как Interval, YearWeek, YearQuarter и другие.

Ответ 5

Решение на самом деле довольно просто (чистая, простая Java):

System.out.println(" NZ Local Time: 2011-10-06 03:35:05");
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
LocalDateTime localNZ = LocalDateTime.parse("2011-10-06 03:35:05",formatter);
ZonedDateTime zonedNZ = ZonedDateTime.of(localNZ,ZoneId.of("+13:00"));
LocalDateTime localUTC = zonedNZ.withZoneSameInstant(ZoneId.of("UTC")).toLocalDateTime();
System.out.println("UTC Local Time: "+localUTC.format(formatter));

ВЫХОД:

 NZ Local Time: 2011-10-06 03:35:05
UTC Local Time: 2011-10-05 14:35:05

Ответ 6

Посмотрел, и я не думаю, что это часовой пояс в Java, который равен GMT + 13. Поэтому я думаю, что вы должны использовать:

Calendar calendar = Calendar.getInstance();
//OR Calendar.getInstance(TimeZone.getTimeZone("GMT"));

calendar.set(Calendar.HOUR_OF_DAY, calendar.get(Calendar.HOUR_OF_DAY)+13);

Date d = calendar.getTime();

(Если после этого изменится "GMT" на этот часовой пояс и удалите вторую строку кода)

ИЛИ

SimpleDateFormat df = new SimpleDateFormat();
df.setTimeZone(TimeZone.getTimeZone("GMT+13"));
System.out.println(df.format(c.getTime()));

Если вы хотите установить определенное время/дату, вы также можете использовать:

    calendar.set(Calendar.DATE, 15);
calendar.set(Calendar.MONTH, 3);
calendar.set(Calendar.YEAR, 2011);
calendar.set(Calendar.HOUR_OF_DAY, 13); 
calendar.set(Calendar.MINUTE, 45);
calendar.set(Calendar.SECOND, 00);

Ответ 7

Joda времени

Классы java.util.Date/Calendar - беспорядок, и его следует избегать.

Обновление: проект Joda-Time находится в режиме обслуживания. Команда советует перейти на классы java.time.

Вот ваш ответ, используя библиотеку Joda-Time 2.3. Очень легко.

Как указано в примере кода, я предлагаю вам использовать названные часовые пояса, где это возможно, чтобы ваше программирование могло обрабатывать Летнее время (DST) и другие аномалии.

Если вы разместили T в середине строки вместо пробела, вы можете пропустить первые две строки кода, имея дело с форматированием для синтаксического анализа строки. Конструктор DateTime может принимать строку в ISO 8601 формат.

// © 2013 Basil Bourque. This source code may be used freely forever by anyone taking full responsibility for doing so.
// import org.joda.time.*;
// import org.joda.time.format.*;

// Parse string as a date-time in UTC (no time zone offset).
DateTimeFormatter formatter = org.joda.time.format.DateTimeFormat.forPattern( "yyyy-MM-dd' 'HH:mm:ss" );
DateTime dateTimeInUTC = formatter.withZoneUTC().parseDateTime( "2011-10-06 03:35:05" );

// Adjust for 13 hour offset from UTC/GMT.
DateTimeZone offsetThirteen = DateTimeZone.forOffsetHours( 13 );
DateTime thirteenDateTime = dateTimeInUTC.toDateTime( offsetThirteen );

// Hard-coded offsets should be avoided. Better to use a desired time zone for handling Daylight Saving Time (DST) and other anomalies.
// Time Zone list… http://joda-time.sourceforge.net/timezones.html
DateTimeZone timeZoneTongatapu = DateTimeZone.forID( "Pacific/Tongatapu" );
DateTime tongatapuDateTime = dateTimeInUTC.toDateTime( timeZoneTongatapu );

Сбросьте эти значения...

System.out.println( "dateTimeInUTC: " + dateTimeInUTC );
System.out.println( "thirteenDateTime: " + thirteenDateTime );
System.out.println( "tongatapuDateTime: " + tongatapuDateTime );

При запуске...

dateTimeInUTC: 2011-10-06T03:35:05.000Z
thirteenDateTime: 2011-10-06T16:35:05.000+13:00
tongatapuDateTime: 2011-10-06T16:35:05.000+13:00

Ответ 8

Я пробовал этот код

try{
            SimpleDateFormat sdf = new SimpleDateFormat("dd-MM-yyyy hh:mm:ss Z");
            Date datetime = new Date();

            System.out.println("date "+sdf.format(datetime));

            sdf.setTimeZone(TimeZone.getTimeZone("GMT"));

            System.out.println("GMT "+ sdf.format(datetime));

            sdf.setTimeZone(TimeZone.getTimeZone("GMT+13"));

            System.out.println("GMT+13 "+ sdf.format(datetime));

            sdf.setTimeZone(TimeZone.getTimeZone("UTC"));

            System.out.println("utc "+sdf.format(datetime));

            Calendar calendar = new GregorianCalendar(TimeZone.getTimeZone("GMT"));

            DateFormat formatter = new SimpleDateFormat("dd MMM yyyy HH:mm:ss z");    
            formatter.setTimeZone(TimeZone.getTimeZone("GMT+13"));  

            String newZealandTime = formatter.format(calendar.getTime());

            System.out.println("using calendar "+newZealandTime);

        }catch (Exception e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }

и получив этот результат

date 06-10-2011 10:40:05 +0530
GMT 06-10-2011 05:10:05 +0000 // here getting 5:10:05
GMT+13 06-10-2011 06:10:05 +1300 // here getting 6:10:05
utc 06-10-2011 05:10:05 +0000
using calendar 06 Oct 2011 18:10:05 GMT+13:00

Ответ 9

Мы можем справиться с этим, используя значение смещения

 public static long convertDateTimeZone(long lngDate, String fromTimeZone,
        String toTimeZone){
    TimeZone toTZ = TimeZone.getTimeZone(toTimeZone);
    Calendar toCal = Calendar.getInstance(toTZ);        

    TimeZone fromTZ = TimeZone.getTimeZone(fromTimeZone);
    Calendar fromCal = Calendar.getInstance(fromTZ);
    fromCal.setTimeInMillis(lngDate);
    toCal.setTimeInMillis(fromCal.getTimeInMillis()
            + toTZ.getOffset(fromCal.getTimeInMillis())
            - TimeZone.getDefault().getOffset(fromCal.getTimeInMillis()));      
    return toCal.getTimeInMillis();
}

Отрывок из тестового кода:

 System.out.println(new Date().getTime())
 System.out.println(convertDateTimeZone(new Date().getTime(), TimeZone
                .getDefault().getID(), "EST"));

Вывод:   1387353270742   1387335270742

Ответ 10

Мы можем получить отметку времени UTC/GMT с указанной даты.

/**
 * Get the time stamp in GMT/UTC by passing the valid time (dd-MM-yyyy HH:mm:ss)
 */
public static long getGMTTimeStampFromDate(String datetime) {
    long timeStamp = 0;
    Date localTime = new Date();

    String format = "dd-MM-yyyy HH:mm:ss";
    SimpleDateFormat sdfLocalFormat = new SimpleDateFormat(format);
    sdfLocalFormat.setTimeZone(TimeZone.getDefault());

    try {

        localTime = (Date) sdfLocalFormat.parse(datetime); 

        Calendar cal = Calendar.getInstance(TimeZone.getTimeZone("UTC"),
                Locale.getDefault());
        TimeZone tz = cal.getTimeZone();

        cal.setTime(localTime);

        timeStamp = (localTime.getTime()/1000);
        Log.d("GMT TimeStamp: ", " Date TimegmtTime: " + datetime
                + ", GMT TimeStamp : " + localTime.getTime());

    } catch (Exception e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }

    return timeStamp;

}

Он вернет время UTC на основе прошедшей даты.

  • Мы можем сделать обратное, как штамп времени UTC, в текущую дату и время (наоборот)

        public static String getLocalTimeFromGMT(long gmtTimeStamp) {
                 try{
                        Calendar calendar = Calendar.getInstance();
                        TimeZone tz = TimeZone.getDefault();
                        calendar.setTimeInMillis(gmtTimeStamp * 1000);
        //              calendar.add(Calendar.MILLISECOND, tz.getOffset(calendar.getTimeInMillis())); 
                        SimpleDateFormat sdf = new SimpleDateFormat("dd-MM-yyyy HH:mm:ss");
                        Date currenTimeZone = (Date) calendar.getTime();
                        return sdf.format(currenTimeZone);
                    }catch (Exception e) {
                    }
                    return "";  
                }
    

Надеюсь, это поможет другим. Спасибо!!

Ответ 11

Быстрый способ:

String dateText ="Thu, 02 Jul 2015 21:51:46";
long hours = -5; // time difference between places

DateTimeFormatter formatter = DateTimeFormatter.ofPattern(E, dd MMM yyyy HH:mm:ss, Locale.ENGLISH);     
LocalDateTime date = LocalDateTime.parse(dateText, formatter);        
date = date.with(date.plusHours(hours));

System.out.println("NEW DATE: "+date);

Выход

НОВАЯ ДАТА: 2015-07-02T16: 51: 46

Ответ 12

public Timestamp convertLocalTimeToServerDatetime(String dt,String timezone){

    String clientDnT = dt ;// "2017-06-01 07:20:00";
    try{
    SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
    Date date = sdf.parse(clientDnT);
    TimeZone tz = TimeZone.getTimeZone(timezone.trim()); // get time zone of user
    sdf.setTimeZone(tz);

    // Convert to servertime zone 
    SimpleDateFormat sdf1 = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
    TimeZone tzInAmerica = TimeZone.getDefault();
    sdf1.setTimeZone(tzInAmerica);

    // assign date to date
    String serverDate = sdf1.format(date);

    // Convert to servertime zone to Timestamp
    Date date2 =  sdf.parse(serverDate);
    Timestamp tsm = new Timestamp(date2.getTime());
    return  tsm;
    }
    catch(Exception e){
        System.err.println(e);
    }

    return null;
}

Ответ 13

Найти длительность или временной интервал с двумя разными часовыми поясами

import org.joda.time.{DateTime, Period, PeriodType}

val s1 = "2019-06-13T05:50:00-07:00"
val s2 = "2019-10-09T11:30:00+09:00"    

val period = new Period(DateTime.parse(s1), DateTime.parse(s2), PeriodType dayTime())

period.getDays
period.getMinutes
period.getHours

период выхода = P117DT13H40M

days = 117
minutes = 40
hours = 13

Ответ 14

Я хотел бы дать современный ответ.

Вы действительно не должны преобразовывать дату и время из строки с одним смещением по Гринвичу в строку с другим смещением по Гринвичу и в другом формате. Скорее в вашей программе храните мгновение (момент времени) как надлежащий объект даты и времени. Только когда вам нужно выдать строку, отформатируйте ваш объект в нужную строку.

java.time

Разбор ввода

    DateTimeFormatter formatter = new DateTimeFormatterBuilder()
            .append(DateTimeFormatter.ISO_LOCAL_DATE)
            .appendLiteral(' ')
            .append(DateTimeFormatter.ISO_LOCAL_TIME)
            .toFormatter();

    String dateTimeString = "2011-10-06 03:35:05";
    Instant instant = LocalDateTime.parse(dateTimeString, formatter)
            .atOffset(ZoneOffset.UTC)
            .toInstant();

Для большинства целей Instant является хорошим выбором для сохранения момента времени. Если вам необходимо четко указать, что дата и время пришли из GMT, используйте вместо этого OffsetDateTime.

Преобразование, форматирование и вывод на печать

    ZoneId desiredZone = ZoneId.of("Pacific/Auckland");
    Locale desiredeLocale = Locale.forLanguageTag("en-NZ");
    DateTimeFormatter desiredFormatter = DateTimeFormatter.ofPattern(
            "dd MMM uuuu HH:mm:ss OOOO", desiredeLocale);

    ZonedDateTime desiredDateTime = instant.atZone(desiredZone);
    String result = desiredDateTime.format(desiredFormatter);
    System.out.println(result);

Это напечатано:

06 Oct 2011 16:35:05 GMT+13:00

Я указал часовой пояс Pacific/Auckland, а не смещение, которое вы упомянули, +13: 00. Я понял, что вы хотели новозеландское время, и Pacific/Auckland лучше расскажет об этом читателю. Часовой пояс также учитывает летнее время (DST), поэтому вам не нужно учитывать это в своем собственном коде (для большинства целей).

Поскольку Oct написан на английском языке, хорошая идея дать форматеру явный языковой стандарт. GMT также может быть локализован, но я думаю, что он просто печатает GMT во всех локалях.

OOOO в строке шаблонов форматирования является одним из способов печати смещения, что может быть лучшей идеей, чем печать аббревиатуры часового пояса, которую вы получили бы из z, поскольку аббревиатуры часового пояса часто бывают неоднозначными. Если вы хотите NZDT (для новозеландского летнего времени), просто поместите вместо него z.

Ваши вопросы

Я отвечу на ваши пронумерованные вопросы относительно современных классов в java.time.

Возможно:

  1. Установить время на объекте

Нет, современные классы неизменны. Вам необходимо с самого начала создать объект с желаемой датой и временем (это имеет ряд преимуществ, в том числе безопасность потоков).

  1. (Возможно) Установить часовой пояс начальной отметки времени

Метод atZone, который я использую в коде, возвращает ZonedDateTime с указанным часовым поясом. Другие классы даты и времени имеют похожий метод, иногда называемый atZoneSameInstant или другими именами.

  1. Отформатируйте отметку времени с помощью новой временной зоны

С java.time преобразование в новый часовой пояс и форматирование - два отдельных шага, как показано.

  1. Вернуть строку с новым часовым поясом.

Да, преобразуйте в нужный часовой пояс, как показано, и отформатируйте, как показано.

Я обнаружил, что каждый раз, когда я пытаюсь установить время следующим образом:

calendar.setTime(new Date(1317816735000L));

используется локальная машина TimeZone. Почему это так?

Это не то, что вы думаете, и это хорошо, если показать только пару (многих) проблем дизайна со старыми классами.

  • Date не имеет часового пояса. Только когда вы печатаете его, его метод toString захватывает ваш локальный часовой пояс и использует его для рендеринга строки. Это верно и для new Date(). Такое поведение смущало многих программистов за последние 25 лет.
  • Calender имеет часовой пояс. Он не меняется, когда вы делаете calendar.setTime(new Date(1317816735000L));.

Ссылка

Учебное пособие по Oracle: Date Time, объясняющее, как использовать java.time.

Ответ 15

отображать дату и время для всех часовых поясов

import java.util.Calendar;
import java.util.TimeZone;
import java.text.DateFormat;
import java.text.SimpleDateFormat;



static final String ISO8601 = "yyyy-MM-dd'T'HH:mm:ssZ";
DateFormat dateFormat = new SimpleDateFormat(ISO8601);
Calendar c = Calendar.getInstance();
String formattedTime;
for (String availableID : TimeZone.getAvailableIDs()) {
    dateFormat.setTimeZone(TimeZone.getTimeZone(availableID));
    formattedTime = dateFormat.format(c.getTime());
    System.out.println(formattedTime + " " + availableID);
}

Ответ 16

Ваш подход работает без каких-либо изменений.

Calendar calendar = Calendar.getInstance(TimeZone.getTimeZone("GMT"));
// Timestamp for 2011-10-06 03:35:05 GMT
calendar.setTime(new Date(1317872105000L));

DateFormat formatter = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss z"); 
formatter.setTimeZone(TimeZone.getTimeZone("GMT+13"));

// Prints 2011-10-06 16:35:05 GMT+13:00
System.out.println(formatter.format(calendar.getTime()));

Ответ 17

Несколько простых способов. Важно помнить, что дата не поддерживает часовой пояс, его единственный номер long millis, как он здесь трактуется.

/**
 * Converts source in GMT+0 to timezone specified by server
 * 
 * @throws IllegalStateException if server timezone wasnt set
 */
public static Date convertGmt(Date source)
{
    if (timeZoneServer == null)
    {
        throw new IllegalStateException("Server timezone wasnt set");
    }

    long rawOffset = timeZoneServer.getRawOffset();

    Date dest = new Date(source.getTime() + rawOffset);

    return dest;
}

/**
 * Converts source in device timezone format to GMT
 */
public static Date convertToGmt(Date source)
{
    int rawOffset = TimeZone.getDefault().getRawOffset();

    Date dest = new Date(source.getTime() - rawOffset);

    return dest;
}

TimezoneServer - это что-то вроде TimeZone timeZoneServer = TimeZone.getTimeZone("GMT+1")