Как преобразовать локальную дату в UTC в Мирте?

В Mirth я получаю локальную строку datetime (201801011000) который мне нужно конвертировать в UTC. Я скоро узнал, используя классический JS new Date() не работает хорошо

Это например:

var d = new Date("2018-01-01 10:00");
logger.info(d.toString());

дает мне Invalid Date,

Итак, после еще нескольких поисков я обнаружил, что могу сделать это:

var d = DateUtil.getDate("yyyyMMddHHmm", "201801011000");

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

Я пытался получить методы, которые я могу использовать с Object.getOwnPropertyNames(d), но это помогает мне TypeError: Expected argument of type object, but instead had type object

Я также попытался найти документацию по Java для DateUtil и попробовал некоторые методы из этого, но ничего не получалось.

Кто-нибудь знает, как я могу преобразовать строку даты из местного времени в UTC? Все советы приветствуются!

5 ответов

Решение

Хорошо, после того, как возиться с этим в течение примерно двух дней, я наконец нашел решение. В конце концов мне пришлось подключиться к Java, но так как я не мог импортировать какие-либо Java-зависимости, мне пришлось использовать их прямой путь к классу (например: java.text.SimpleDateFormat).

В конце концов это то, что сработало для меня:

var datestr = "201207011000".slice(0, 12);  // This is just a datetime string to test with

var formatter_hl7 = new java.text.SimpleDateFormat("yyyyMMddHHmm");
formatter_hl7.setTimeZone(java.util.TimeZone.getTimeZone("CET"));
var formatter_utc = new java.text.SimpleDateFormat("yyyy-MM-dd HH:mm");
formatter_utc.setTimeZone(java.util.TimeZone.getTimeZone("UTC"));

var date_in_utc = formatter_utc.format(formatter_hl7.parse(date_str));

Несмотря ни на что, я желаю вам прекрасного дня!

ТЛ; др

  • Не использовать DateUtil что бы это ни было. (Возможно, библиотека Apache DateUtils?)
  • Не используйте ужасные старые классы даты и времени, такие как java.util.Date,
  • Используйте современные ведущие классы java.time.

Код для разбора строки без смещения, затем присвоение нулевого смещения для самого UTC.

LocalDateTime                // Represents a date and a time-of-day but without any concept of time zone or offset-from-UTC. NOT a moment, NOT a point on the timeline.
.parse( 
    "201801011000" ,
     DateTimeFormatter.ofPattern( "uuuuMMddHHmm" )
)  
.atOffset( ZoneOffset.UTC )  // Assign an offset-from-UTC. Do this only if you are CERTAIN this offset was originally intended for this input but was unfortunately omitted from the text. Returns an `OffsetDateTime`.
.toInstant()                 // Extract an `Instant` from the `OffsetDateTime`. Basically the same thing. But `Instant` is always in UTC by definition, so this type is more appropriate if your intention is to work only in UTC. On the other hand, `Instant` is a basic class, and `OffsetDateTime` is more flexible such as various formatting patterns when generating `String` object to represent its value.

Использование java.time

Современный подход в Java использует классы java.time. Эта ведущая в отрасли инфраструктура вытеснила ужасно хлопотные старые классы даты и времени, такие как Date, Calendar, а также SimpleDateFormat,

DateTimeFormatter

Разобрать вашу входную строку. Определите шаблон форматирования для соответствия.

DateTimeFormatter f = DateTimeFormatter.ofPattern( "uuuuMMddHHmm" ) ;
String input = "201801011000" ;

LocalDateTime

Разбирать как LocalDateTime потому что в вашем входе отсутствует индикатор для часового пояса или смещения от UTC.

LocalDateTime ldt = LocalDateTime.parse( input , f ) ;

Отсутствие зоны или смещения означает, что это не представляет момент, не является точкой на временной шкале. Вместо этого это представляет потенциальные моменты в диапазоне около 26-27 часов, в диапазоне часовых поясов по всему миру.

OffsetDateTime

Если вы точно знаете, что эта дата и время дня должны были представлять момент в UTC, примените константу ZoneOffset.UTC чтобы получить OffsetDateTime объект.

OffsetDateTime odt = ldt.atOffset( ZoneOffset.UTC ) ;

ZonedDateTime

Ваш вопрос расплывчат. Похоже, вы знаете конкретный часовой пояс, предназначенный для этого ввода. Если это так, назначьте ZoneId чтобы получить ZonedDateTime объект.

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

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

ZoneId z = ZoneId.of( "Africa/Tunis" ) ;
ZonedDateTime zdt = ldt.atZone( z ) ;

Instant

Быстрый способ вернуться обратно в UTC - это извлечь Instant объект. Instant всегда в UTC.

Instant instan = zdt.toInstant() ;

ISO 8601

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

Классы java.time по умолчанию используют форматы ISO 8601 при разборе / генерации строк. ZonedDateTime::toString Метод мудро расширяет стандарт, добавляя название зоны в квадратных скобках.

Instant instant = Instant.parse( "2018-07-23T16:18:54Z" ) ;  // `Z` on the end means UTC, pronounced “Zulu”. 
String output = instant.toString() ;  // 2018-07-23T16:18:54Z

И всегда включайте смещение и часовой пояс в вашей строке. Пропустить смещение / зону на мгновение - все равно что опустить валюту для цены: все, что у вас осталось, - это неоднозначное число, ничего не стоящее. На самом деле, хуже, чем ничего, так как это может вызвать все виды путаницы и ошибок.


О java.time

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

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

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

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

Где взять классы java.time?

  • 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

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

В моем проекте есть функция для конвертации datestring местное время до UTC,

function getDateInUTC(dateString) {
    return new java.text.SimpleDateFormat("yyyy-MM-dd HH:mm").setTimeZone(java.util.TimeZone.getTimeZone("UTC")).format(new java.text.SimpleDateFormat("yyyyMMddHHmm").setTimeZone(java.util.TimeZone.getTimeZone("CET")).parse(dateString));
}

Наслаждаться:)

Вы должны использовать последние классы java.time предоставлено с Java8.

Шаги следующие:

Шаг 1. парсить String в LocalDateTime

Шаг 2. Перерабатывать LocalDateTime к ZonedDateTime и тогда мы можем конвертировать между разными timezone,

Надеюсь, что это поможет:

В Мирте вы можете написать как:

String str = "201207011000"; 
var date_in_utc =java.time.format.DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm")
                .format(java.time.ZonedDateTime.of(java.time.LocalDateTime
                .parse(str,java.time.format.DateTimeFormatter
                .ofPattern("yyyyMMddHHmm")),java.time.ZoneId.of("CET"))
                .withZoneSameInstant(java.time.ZoneOffset.UTC));

Полный фрагмент:

ZoneId cet = ZoneId.of("CET");
String str = "201207011000";
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyyMMddHHmm");
LocalDateTime localtDateAndTime = LocalDateTime.parse(str, formatter);
ZonedDateTime dateAndTimeInCET = ZonedDateTime.of(localtDateAndTime, cet );
System.out.println("Current date and time in a CET timezone : " + dateAndTimeInCET);
ZonedDateTime utcDate = dateAndTimeInCET.withZoneSameInstant(ZoneOffset.UTC);
System.out.println("Current date and time in UTC : " + utcDate);
System.out.println("Current date and time in UTC : " + DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm").format(utcDate));

Дай это крик

var d = DateUtil.getDate("yyyyMMddHHmm", "201801011000");
var utcD = new Date(d).toISOString();

изменить: Информация о.toISOString () https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date/toISOString

Другие вопросы по тегам