Как преобразовать (Строка в UTC) Дата в миллисекунды, не нарушая его часовой пояс в Java - PullRequest
0 голосов
/ 10 сентября 2018

Рассмотрим ниже строку UTC время, и я хочу эквивалентное время в миллисекундах с использованием Java.

String flcDate = "2018-09-07 05:45:00.0";
String geofenceDate = "2018-07-27 08:42:20";

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

public static long stringToMilliSeconds(String string) throws ParseException {

          SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss");
          Calendar calendar = Calendar.getInstance(TimeZone.getTimeZone("UTC"));
          TimeZone fromTimeZone = calendar.getTimeZone();
          TimeZone.setDefault(TimeZone.getTimeZone("UTC"));
          calendar.setTimeZone(fromTimeZone);

          calendar.setTime(sdf.parse(string));
          System.out.println(calendar.getTime().toString());


          return calendar.getTime().getTime();
    }

Ответы [ 3 ]

0 голосов
/ 10 сентября 2018

Конечно, вы должны использовать новые классы java.time *. Но если это невозможно, попробуйте это:

public static long stringToMilliSeconds(String string) throws ParseException {

          SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss");
          sdf.setTimeZone(TimeZone.getTimeZone("UTC"));
          Date date = sdf.parse(string);
          System.out.println(date.getTime());

          return date.getTime();
    }
0 голосов
/ 10 сентября 2018

java.time

Этот должен быть достаточно гибким, чтобы принять обе ваши строки:

private static DateTimeFormatter FORMATTER = new DateTimeFormatterBuilder()
        .append(DateTimeFormatter.ISO_LOCAL_DATE)
        .appendLiteral(' ')
        .append(DateTimeFormatter.ISO_LOCAL_TIME)
        .toFormatter();

public static long stringToMilliseconds(String string) {
    return LocalDateTime.parse(string, FORMATTER)
            .toInstant(ZoneOffset.UTC)
            .toEpochMilli();
}

Демонстрация:

    String flcDate = "2018-09-07 05:45:00.0";
    System.out.println(stringToMilliseconds(flcDate)); // 1536299100000
    String geofenceDate = "2018-07-27 08:42:20";
    System.out.println(stringToMilliseconds(geofenceDate)); // 1532680940000

Вывод в комментариях.

Встроенный DateTimeFormatter.ISO_LOCAL_DATE принимает строку даты, например 2018-09-10.DateTimeFormatter.ISO_LOCAL_TIME принимает временную строку, такую ​​как 10:15 или 05: 45: 00.0.Секунды и доли секунды являются необязательными, и их доля может составлять до 9 десятичных знаков.Я использую DateTimeFormatterBuilder для объединения двух форматеров в один с пробелом между датой и временем.

«local» в LocalDateTime (и других именах классов java.time) означает «без времени»информация о зоне », поэтому использование этого класса гарантирует, что ни один непреднамеренный часовой пояс, например, ваш часовой пояс, не будет мешать.И использование ZoneOffset.UTC при преобразовании в Instant гарантирует, что мы получим время в UTC.

Что пошло не так в вашем коде?

Несмотря на ваши операции с часовыми поясами, ваш SimpleDateFormat использует ваш местный часовой пояс и, следовательно, создает момент времени 2018-09-07 05: 45: 00.0 в вашем местном часовом поясе, а не в UTC.После того, как эта ошибка введена, она распространяется через ваш Calendar объект и возвращается в ваше возвращаемое значение.

Я рекомендую вам вообще не использовать SimpleDateFormat, Calendar и TimeZone.Эти классы давно устарели, и, в частности, SimpleDateFormat, как известно, хлопотно.Сегодня у нас намного лучше в java.time, современном Java-API даты и времени.

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

0 голосов
/ 10 сентября 2018

Используется местное время и дата для преобразования строки.

return LocalDateTime.parse("2018-09-07 05:45:00.0", 
                           DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss.S"))
     .toInstant(ZoneOffset.UTC)
     .toEpochMilli(); //1536299100000

Результирующий long представляет эпоху миллисекунд для введенной даты / времени (время UTC):

Instant.ofEpochMilli(1536299100000L)  ==> 2018-09-07T05:45:00Z

А для второй строки DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss") может использоваться в качестве средства форматирования.

...