Дата анализа Kotlin в формате: с 1 января 2023 г., 00:00 по 01.01.2023, 00:00:00.0

Похоже, что Котлин очень специфичен в отношении форматов даты. Я получаю строку в этом формате "Jan 1 2023 12:00AM" и хочу преобразовать ее в этот формат "2023-01-01 00:00:00.0". Я осмотрелся, но не смог найти решения.

fun FormatDateTime(dateTimeString: String): String{
    val DATE_FORMAT = DateTimeFormatter.ofPattern("MMM dd uuuu")
    var dat = dateTimeString.substring(0, dateTimeString.length-7).trim() //Removing ' 12:00AM' part
    val changeDate = LocalDateTime.parse(dat, DATE_FORMAT)
    //After getting the date, reformat it again to '2023-01-01 00:00:00.0'

   return "" //return formatted date string, currently returning empty string
}

Но это провал. Ошибка следующая - java.time.format.DateTimeParseException: Text 'Jan 1 2023' could not be parsed at index 4. Есть ли способ добиться этого?

Внес некоторые изменения в ответ Слоу и не уверен, что это сломается, в каких сценариях, за исключением случаев, когда код выполняется в разных географических местах.

fun convert(input: String): String {
    var sanitizedInput = input.replace("\\s+".toRegex(), " ").trim()

    return LocalDateTime.parse(sanitizedInput, DateTimeFormatter.ofPattern("MMM d uuuu hh:mma"))
        .format(DateTimeFormatter.ofPattern("uuuu-MM-dd HH:mm:ss.S"))
}

Объясните, пожалуйста, для чего используется приемник String и что такое aVal. Кроме того, почему используется только длина input?

Leviathan 06.08.2024 23:25

Добавлены комментарии и переименованы переменные для ясности.

Karan 06.08.2024 23:34

Я не добавил ошибку, так как думаю, что есть лучший способ сделать это. Однако ошибка следующая: java.time.format.DateTimeParseException: текст «1 января 2023 г.» не удалось проанализировать по индексу 4.

Karan 06.08.2024 23:45

Не забудьте указать локаль в форматтерах.

Anonymous 07.08.2024 09:26

Я вставил исключение в вопрос. Нам будет легче понять вашу проблему и направить вас по правильному пути.

Anonymous 07.08.2024 09:30

Время всегда 12 утра (12 ночи)? И должно ли время суток всегда быть 00:00:00.0 или это должно быть то же время суток, что и во входных данных?

Anonymous 07.08.2024 09:43

Как правило, вам не следует хранить дату и время в строке и, следовательно, никогда не возникнет необходимости конвертировать строку одного формата в строку другого формата. Сохраните дату и время в формате ZonedDateTime, LocalDateTime или другом подходящем типе даты и времени. Когда вы получаете строковый ввод, немедленно анализируйте его. Если ваш вывод предназначен для вашей базы данных, не используйте для этого строку. Сохраните LocalDateTIme или OffsetDateTime через JDBC или JPA.

Anonymous 07.08.2024 09:49

Также рекомендуется добавить Locale к вашему DateTimeFormatter (если вам необходимо его использовать), иначе формат будет зависеть от значения по умолчанию Locale, что может привести к неожиданным сценариям при анализе String, содержащих такие сокращения, как MMM.

deHaar 07.08.2024 10:49
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
В компьютерном программировании биты играют важнейшую роль в представлении и манипулировании данными на двоичном уровне. Побитовые операции...
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Приходилось ли вам сталкиваться с требованиями, в которых вас могли попросить поднять тревогу или выдать ошибку, когда метод Java занимает больше...
Полный курс Java для разработчиков веб-сайтов и приложений
Полный курс Java для разработчиков веб-сайтов и приложений
Получите сертификат Java Web и Application Developer, используя наш курс.
4
8
50
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Вы используете шаблон MMM dd uuuu для анализа входной строки. dd означает, что он ожидает, что дни, состоящие из одной цифры, будут дополнены ведущим 0. Но ваш пример ввода, Jan 1 2023 12:00AM, не имеет этого дополнения. Отсюда ошибка под индексом 4. Вам следует использовать d вместо dd.

Вам также следует рассмотреть возможность анализа всей входной строки вместо подстроки. Затем используйте truncatedTo API объекта LocalDateTime, чтобы установить время на ноль. Я предполагаю, что это то, что вам нужно, поскольку в настоящее время вы пытаетесь удалить значение времени из входной строки, а время вывода вашего примера — полночь.

Судя по вашему вопросу, следующий пример соответствует вашим потребностям:

import java.time.LocalDateTime
import java.time.format.DateTimeFormatter
import java.time.temporal.ChronoUnit
import java.util.Locale

val INPUT_FORMAT = DateTimeFormatter.ofPattern("MMM d uuuu hh:mma", Locale.US)
val OUTPUT_FORMAT = DateTimeFormatter.ofPattern("uuuu-MM-dd HH:mm:ss.S", Locale.US)

fun main() {
    val input = "Jan 1 2023 12:00AM"
    println("$input => ${convert(input)}")
}

fun convert(input: String): String {
    return LocalDateTime.parse(input, INPUT_FORMAT)
            .truncatedTo(ChronoUnit.DAYS)
            .format(OUTPUT_FORMAT)
}

Выход:

Jan 1 2023 12:00AM => 2023-01-01 00:00:00.0

Я явно указал локаль, чтобы локализуемые части входной строки («Январь», «AM»/«PM») правильно анализировались. Для примера я выбрал Locale.US, но вы можете использовать любую локаль, в которой используются правильные значения для MMM и a. Или даже позвольте локали определяться конфигурацией во время выполнения.

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


Обратите внимание, что альтернативой truncatedTo(ChronoUnit.DAYS) является with(LocalTime.MIDNIGHT).

Хороший ответ, просто интересно. Я внес некоторые изменения в ваш код и получаю тот же результат со следующим кодом. Я знаю, что что-то может сломаться, но не знаю, что именно. Пожалуйста, посмотрите: fun Convert(input: String): String { var sanitizedInput = input.replace("\\s+".toRegex(), " ").trim() return LocalDateTime.parse(sanitizedInput, DateTimeFormatter.ofPattern( "МММ д уууу чч:мма")) .format(DateTimeFormatter.ofPattern("уууу-ММ-дд ЧЧ:мм:сс.С")) }

Karan 07.08.2024 01:19
12:00AM то же самое, что 00:00:00.0. Так не является ли сокращение до целых дней риском выбросить время суток, которое мы хотели бы сохранить? В любом случае это не кажется необходимым.
Anonymous 07.08.2024 09:33

@Anonymous Вопрос включает //Removing ' 12:00AM' part, но вывод примера все еще содержит 00:00:00.0, поэтому я предположил, что ОП хочет, чтобы время вывода всегда было 00:00:00.0, даже если время ввода отличается от 12:00AM.

Slaw 07.08.2024 09:40

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