Старый API (с классами Calendar
и SimpleDateFormat
) устарел и имеет множество проблем< /а>.
Вам следует рассмотреть возможность использования более новых API. Если вы используете Java 8, рассмотрите возможность использования нового java. API времени. Это проще, меньше ошибок и менее подвержено ошибкам, чем старые API .
Если вы используете Java ‹= 7, вы можете использовать ThreeTen Backport, отличный бэкпорт для новых классов даты/времени Java 8. А для Android есть ThreeTenABP (подробнее о том, как его использовать здесь).
Код ниже работает для обоих. Единственная разница заключается в именах пакетов (в Java 8 — java.time
, а в ThreeTen Backport (или ThreeTenABP для Android) — org.threeten.bp
), но имена классов и методов одинаковы.
Если вы работаете с датами/временем, содержащими смещение, лучше всего использовать класс OffsetDateTime
, который представляет дату и время со смещением. И у него уже есть метод парсинга String
:
// parse a date string with offset -07:00
String strDate = "2017-06-19T17:50:51.000-07:00";
OffsetDateTime dt = OffsetDateTime.parse(strDate);
System.out.println(dt.toString()); // 2017-06-19T17:50:51-07:00
Вывод будет:
2017-06-19T17:50:51-07:00
Обратите внимание, что по умолчанию метод toString()
не показывает доли секунд, потому что они равны нулю. Если вы хотите всегда показывать эти 3 цифры, вы можете использовать DateTimeFormatter
:
// use a formatter to always print fraction-of-second with 3 digits
DateTimeFormatter fmt = DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:mm:ss.SSSZZZZZ");
System.out.println(fmt.format(dt)); // 2017-06-19T17:50:51.000-07:00
В этом случае на выходе будет:
2017-06-19T17:50:51.000-07:00
Тестирование с разными смещениями:
// offset +03:00
dt = OffsetDateTime.parse("2017-06-19T17:50:51.000+03:00");
System.out.println(fmt.format(dt)); // 2017-06-19T17:50:51.000+03:00
// UTC: "Z" == offset zero (or "+00:00")
dt = OffsetDateTime.parse("2017-06-19T17:50:51.000Z");
System.out.println(fmt.format(dt)); // 2017-06-19T17:50:51.000Z
dt = OffsetDateTime.parse("2017-06-19T17:50:51.000+00:00");
System.out.println(fmt.format(dt)); // 2017-06-19T17:50:51.000Z
Если вам по-прежнему приходится использовать старый API (java.util.Calendar
), вы можете легко преобразовать его в новые классы и обратно.
Если пакет java.time
доступен, вы можете сделать:
// converting the OffsetDateTime to a Calendar
dt = OffsetDateTime.parse("2017-06-19T17:50:51.000Z");
Calendar c = Calendar.getInstance();
// setting the epoch milli to calendar
c.setTimeInMillis(dt.toInstant().toEpochMilli());
// converting Calendar back to OffsetDateTime (using UTC offset)
dt = OffsetDateTime.ofInstant(c.toInstant(), ZoneOffset.UTC);
// converting Calendar back to OffsetDateTime (using +03:00 offset)
dt = OffsetDateTime.ofInstant(c.toInstant(), ZoneOffset.ofHours(3));
Если вы используете ThreeTenABP, метод c.toInstant()
будет недоступен. Но вы можете использовать класс org.threeten.bp.DateTimeUtils
для его преобразования. Итак, вместо c.toInstant()
можно использовать DateTimeUtils.toInstant(c)
:
// conversion for ThreeTenABP
// converting Calendar back to OffsetDateTime (using UTC offset)
dt = OffsetDateTime.ofInstant(DateTimeUtils.toInstant(c), ZoneOffset.UTC);
// converting Calendar back to OffsetDateTime (using +03:00 offset)
dt = OffsetDateTime.ofInstant(DateTimeUtils.toInstant(c), ZoneOffset.ofHours(3));
Обновление: API YouTube
Я проверил документацию по API YouTube (не уверен, что это то, что вы используете), и в примерах он устанавливает scheduledStartTime
в дату/время в формате UTC:
broadcastSnippet.setScheduledStartTime(new DateTime("2024-01-30T00:00:00.000Z"));
Согласно документам, это поле имеет следующий формат:
Дата и время начала трансляции. Значение указывается в формате ISO 8601 (YYYY-MM-DDThh:mm:ss.sZ
).
Итак, нам просто нужно создать средство форматирования, чтобы получить String
в таком формате:
// your date/time, in -07:00 offset
String strDate = "2017-06-19T17:50:51.000-07:00";
OffsetDateTime odt = OffsetDateTime.parse(strDate);
// formatter
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:mm:ss.SSSX");
// convert to UTC
String utc = formatter.format(odt.withOffsetSameInstant(ZoneOffset.UTC));
System.out.println(utc); // 2017-06-20T00:50:51.000Z
Вывод будет в том же формате, что и в примере с YouTube:
2017-06-20T00:50:51.000Z
person
Community
schedule
12.06.2017