Конвертировать Дата / Время для данного часового пояса-java



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



2011-10-06 03:35:05


Я пробовал около 100 различных комбинаций параметра dateformat, часовой пояс, дата, 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));


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



можно:




  1. установите время на объекте (календарь / дата / метка времени)

  2. (возможно) установите часовой пояс начальной отметки времени (календарь.setTimeZone(...))

  3. форматирование метки времени с новым часовым поясом (форматер.setTimeZone(...)))

  4. возвращает строку с новым временем часового пояса. (форматер.формат(календарь.getTime ()))


заранее спасибо за любую помощь :D

835   14  

14 ответов:

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

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

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

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

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

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

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

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

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

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

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

  1. установить время на объект (Дата, календарь и т. д.).
  2. установите часовой пояс на объекте форматирования.
  3. возвращает строку из праматерии.

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

tl; dr

если задан вход 1317816735000L...

Instant.ofEpochMilli( 1_317_816_735_000L )     // Represent a moment in UTC using a count of milliseconds since the epoch reference of 1970-01-01T00:00Z.
.atZone( ZoneId.of( "Pacific/Auckland" ) )     // Adjust from UTC into the wall-clock time used by the people of a certain region (a time zone). Returns a `ZonedDateTime` object.
.format(                 
    DateTimeFormatter.ofLocalizedDateTime( FormatStyle.MEDIUM )
    .withLocale( new Locale( "en" , "NZ" ) )   // Locale specifies the human language and cultural norms used in localization.
)                                              // Returns a `String` object that represents the value of our `ZonedDateTime` object’s value.

если задан вход 2011-10-06 03:35:05...

LocalDateTime.parse(                  // Parse input string lacking any indicator of time zone or offset-from-UTC using the `LocalDateTime` class.
    "2011-10-06 03:35:05"
    .replace( " " , "T" )             // Comply with ISO 8601 standard by replacing SPACE in the middle with a `T`.
)                                     // Returns a `LocalDateTime` object.
.atZone(                              // Adjust from UTC into the wall-clock time used by the people of a certain region (a time zone). Returns a `ZonedDateTime` object.
    ZoneId.of( "Pacific/Auckland" )   // Always specify a time zone by `Continent/Region` name. Never use 3-4 pseudo-time-zones such as `PST`, `CST`, or `IST`.
)                                     // Returns a `ZonedDateTime` object.

java.время

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

ISO 8601

ваша входная строка почти в стандарте ISO 8601 формат. Просто замените пространство в середине на T.

String input = "2011-10-06 03:35:05".replace( " " , "T" ) ;  // Comply with ISO 8601 standard format by replacing the SPACE with a `T`.

The java.время классы используют эти стандартные форматы по умолчанию при разборе / генерации строк. Поэтому нет необходимости указывать шаблон форматирования.

LocalDateTime

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

LocalDateTime ldt = LocalDateTime.parse( input );

ZoneOffset

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

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

OffsetDateTime

применить его, чтобы получить OffsetDateTime, теперь режим обслуживания, советует миграция в java.время классы.

узнать больше, смотрите Oracle Tutorial. Поиск переполнения стека для многих примеров и объяснений. Спецификация является JSR 310.

вы можете обменять java.время объекты непосредственно с вашей базой данных. Используйте - драйвера соответствуют JDBC 4.2 или позже. Нет необходимости в строках, нет необходимости в java.sql.* классы.

где получить java.время занятий?

  • Java SE 8,Java SE 9,Java SE 10, и позже
    • встроенный.
    • часть стандартного Java API с комплектной реализацией.
    • Java 9 добавляет некоторые незначительные функции и исправления.
  • Java SE 6 и Java SE 7
    • большая часть java.функциональность time обратно портирована на Java 6 & 7 в ThreeTen-Backport.
  • Android

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

посмотрел вокруг, и я не думаю, что есть часовой пояс в 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" на этот часовой пояс и удалите 2-ю строку кода)

или

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

решение на самом деле довольно простое (чистая, простая 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

Joda Времени

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

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

вот ваш ответ, используя библиотеку 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

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

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

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

 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

мы можем получить отметку времени 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 "";  
                }
    

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

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

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

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

какой-то простой способ. Одна важная вещь, чтобы помнить, что дата не поддерживает часовой пояс, его только 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")

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

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

Comments

    Ничего не найдено.