Конвертировать Дата / Время для данного часового пояса-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?
можно:
- установите время на объекте (календарь / дата / метка времени)
- (возможно) установите часовой пояс начальной отметки времени (календарь.setTimeZone(...))
- форматирование метки времени с новым часовым поясом (форматер.setTimeZone(...)))
- возвращает строку с новым временем часового пояса. (форматер.формат(календарь.getTime ()))
заранее спасибо за любую помощь :D
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 миллисекундах с момента эпохи. Это означает, что это проще всего, если вы работаете без использования часовых поясов вообще, за исключением форматирования строки для пользователя.
поэтому я бы пропустил большинство шагов, которые вы предложили.
- установить время на объект (Дата, календарь и т. д.).
- установите часовой пояс на объекте форматирования.
- возвращает строку из праматерии.
кроме того, вы можете использовать Джода времени. Я слышал, что это гораздо более интуитивный 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
- более поздние версии Android bundle реализации java.время занятий.
- для более ранних Android ( ThreeTenABP проект адаптируется ThreeTen-Backport (упоминалось выше). Смотрите как использовать ThreeTenABP....
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