Содержание

Как распарсить строку java

как правильно распарсить строку в java

Есть строка add J. Martin «A Song of Ice and Fire» и мне нужно разбить ее на три части. Первая — это add , вторая автор и третья название книги .

Подскажите как лучше.

Нашел способ такой:

но каждый раз после этого собирать по кусочкам как-то не ок, какие есть еще способы? Спасибо!

Можно использовать группы для этого. Группы задаются в скобках, нумерация с 1. Нулевая группа возвращает строку целиком.

Обработка строк в Java. Часть II: Pattern, Matcher

Что Вы знаете о обработке строк в Java? Как много этих знаний и насколько они углублены и актуальны? Давайте попробуем вместе со мной разобрать все вопросы, связанные с этой важной, фундаментальной и часто используемой частью языка. Наш маленький гайд будет разбит на две публикации:

Регулярные выражения

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

Механизм

Существует две базовые технологии, на основе которых строятся механизмы РВ:

  • Недетерминированный конечный автомат (НКА) — «механизм, управляемый регулярным выражением»
  • Детерминированный конечный автомат (ДКА) — «механизм, управляемый текстом»

ДКА — механизм, который анализирует строку и следит за всеми «возможными совпадениями». Его работа зависит от каждого просканированного символа текста (то есть ДКА «управляется текстом»). Даний механизм сканирует символ текста, обновляет «потенциальное совпадение» и резервирует его. Если следующий символ аннулирует «потенциальное совпадение», то ДКА возвращается к резерву. Нет резерва — нет совпадений.

Логично, что ДКА должен работать быстрее чем НКА (ДКА проверяет каждый символ текста не более одного раза, НКА — сколько угодно раз пока не закончит разбор РВ). Но НКА предоставляет возможность определять ход дальнейших событий. Мы можем в значительной степени управлять процессом за счет правильного написания РВ.

Регулярные выражения в Java используют механизм НКА.

Эти виды конечных автоматов более детально рассмотрены в статье «Регулярные выражения изнутри».

Подход к обработке

В языках программирования существует три подхода к обработке РВ:

  • интегрированный
  • процедурный
  • объектно-ориентированный

Для обработки регулярных выражений в Java используют объектно-ориентированный подход.

Реализация

Pattern

Класс Pattern представляет собой скомпилированное представление РВ. Класс не имеет публичных конструкторов, поэтому для создания объекта данного класса необходимо вызвать статический метод compile и передать в качестве первого аргумента строку с РВ:

Также в качестве второго параметра в метод compile можно передать флаг в виде статической константы класса Pattern, например:

Таблица всех доступных констант и эквивалентных им флагов:

ConstantEquivalent Embedded Flag Expression
1Pattern. CANON_EQ
2Pattern.CASE_INSENSITIVE(?i)
3Pattern.COMMENTS(?x)
4Pattern.MULTILINE(?m)
5Pattern.DOTALL(?s)
6Pattern.LITERAL
7Pattern.UNICODE_CASE(?u)
8Pattern.UNIX_LINES(?d)

Иногда нам необходимо просто проверить есть ли в строке подстрока, что удовлетворяет заданному РВ. Для этого используют статический метод matches, например:

Также иногда возникает необходимость разбить строку на массив подстрок используя РВ. В этом нам поможет метод split:

Matcher и MatchResult

Matcher — класс, который представляет строку, реализует механизм согласования (matching) с РВ и хранит результаты этого согласования (используя реализацию методов интерфейса MatchResult). Не имеет публичных конструкторов, поэтому для создания объекта этого класса нужно использовать метод matcher класса Pattern:

Но результатов у нас еще нет. Чтобы их получить нужно воспользоваться методом find. Можно использовать matches — этот метод вернет true только тогда, когда вся строка соответствует заданному РВ, в отличии от find, который пытается найти подстроку, которая удовлетворяет РВ. Для более детальной информации о результатах согласования можно использовать реализацию методов интерфейса MatchResult, например:

Парсинг строк в Java

Если в метод передать строку, которая не является целочисленным значением, будет получена ошибка java.lang.NumberFormatException , которая будет сообщать, что полученная строка не является целочисленным значением.

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

parseInt() — может работать с отрицательными числами. Для этого строка должна начинаться с символа “-”.

parseInt() — не может распарсить строку, если числовое значение выходит за пределы типы int (-2147483648 .. 2147483647).

Как разбить строку на массив java

Как раздедить строку на массив с разными разделителями Java

Метод split в качестве первого аргумента принимает регулярное выражение, соотвестственно там можно перечислить несколько разделителей, разделенных в свою очередь символом | :

Если Вам нужно тоько имя файла, разделенное по точкам (путь не нужен), то:

Всё ещё ищете ответ? Посмотрите другие вопросы с метками java массивы строки split или задайте свой вопрос.

дизайн сайта / логотип © 2021 Stack Exchange Inc; материалы пользователей предоставляются на условиях лицензии cc by-sa. rev 2021.11.26.40833

Нажимая «Принять все файлы cookie» вы соглашаетесь, что Stack Exchange может хранить файлы cookie на вашем устройстве и раскрывать информацию в соответствии с нашей Политикой в отношении файлов cookie.

3.8. Java примеры — Разбиение строки на слова и символы в массив и по разделителю

Следующий пример показывает как разделить строку в Java по разделителю с помощью метода split() и вывести подстроку.

Результат

Получим следующий результат:

Решение 2: разбить строку на слова

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

Результат

Получим следующий результат:

Решение 3: разбить строку на символы в массив

Следующий пример показывает как разбить строку на массив по символу. Для этого просто преобразуем строку в массив с помощью метода toCharArray().

Как разделить строку в Java

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

  • Автор записи

В Java мы можем использовать String#split для разделения строки. split() принимает регулярное выражение в качестве аргумента, что означает, что мы можем разделить строку с помощью шаблона регулярного выражения.

  1. Разделить строку
  2. Разделить строку по ограничению
  3. Разделение строки специальными символами регулярного выражения
  4. Разделите строку несколькими разделителями
  5. Разделите строку и Java 8
  6. Разделить строку пробелами
  7. Разделить строку на новую строку
  8. СтрокоКенизатор (устаревший)

1. Разделить строку

Ниже приведен пример разделения строки с помощью тире — .

2. Разделить строку по ограничению

split() также поддерживает второй аргумент limit , который управляет длиной возвращаемого массива. Длина массива не будет превышать предел , а последняя запись массива содержит оставшиеся входные данные после последнего совпадающего разделителя.

3. Разделите строку специальными символами регулярного выражения.

3.1 split() принимает регулярное выражение в качестве аргумента, и в регулярном выражении 12 специальных символов имеют особое значение:

  1. Точка или точка .
  2. Знак плюс +
  3. Звездочка или звезда *
  4. Знак вопроса ?
  5. Каретка ^
  6. Знак доллара $
  7. Открывающая и закрывающая скобки ( и )
  8. Открывающая квадратная скобка [
  9. Открывающая фигурная скобка <
  10. Символ трубы |
  11. Обратная косая черта \

P. S Обе закрывающие квадратные скобки ] и закрывающая фигурная скобка > это обычный персонаж, не нужно убегать.

3.2 Если мы хотим использовать любой из вышеперечисленных специальных символов в качестве разделителя, мы должны избежать его. Например, если мы хотим разделить строку вертикальной чертой или символом трубы | (специальный символ регулярного выражения), что означает или в регулярном выражении, мы должны избежать символа |, используя один из следующих способов:

3.3 Полный пример разделения строки символом /.

3.4 Полный пример разделения строки символом обратной косой черты \ .

4. Разделите строку несколькими разделителями

Если мы хотим разделить строку на несколько разделителей, просто заключите все разделители в квадратные скобки [ ] .

5. Разделите строку и Java 8

5.1 Для потока Java 8 мы можем использовать .Разделенный поток чтобы разделить строку.

5.2 Мы также можем использовать Arrays.stream для преобразования массива в поток.

6. Разделите строку пробелом или несколькими пробелами

Мы можем использовать \\s+ (один или несколько пробелов) для разделения строки пробелами.

7. Разделить строку на новую строку

В другой операционной системе есть другая новая строка

  • Unix, Linux или Mac \r
  • Окна \r\n

В примере используется регулярное выражение \\r?\\n для разделения строки на новую строку и API потока для обрезки и фильтрации пустой строки.

8. Пример StringTokenizer (устаревший)

В старые времена разработчики Java использовали класс StringTokenizer для разделения строки.

P.S То Строка#разделить() доступен начиная с JDK 1.4.

Примечание Этот StringTokenizer является устаревшим классом, сохраненным по соображениям совместимости; использование не рекомендуется! Пожалуйста, обновите код до строки#split() .

Подборка полезных алгоритмов для собеседований: задачи на строки

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

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

Как работать со строками

В Java строка как класс представляет из себя массив символов и ещё несколько полей и методов. Подробнее об этом можно прочитать в нашей статье. Мы выделили несколько самых востребованных методов для работы со строками:

toCharArray() // Возвращает массив символов строки
charAt(int x) // Возвращает символ, находящийся на указанной позиции
length() // Возвращает длину строки. Обратите внимание, это не поле, в отличие от массива
substring(int beginIndex) // Возвращает подстроку от указанного индекса и до конца строки
substring(int beginIndex, int endIndex) // Возвращает подстроку между указанными индексами
Integer.  3.

Для перевода в постфиксную нотацию необходимо знание такой структуры, как стек. Примеры реализации обратной польской записи можно найти на Wikiversity, а описание алгоритма на английском языке можно прочесть в статье на programcreek.com.

Нахождение максимальной подстроки-палиндрома

Палиндромом — строка, которая читается одинаково в обе стороны, т.е. такая строка S длины n, что S[i] = S[n - 1 - i], где i принимает значения от 0 до n - 1.

Решение «в лоб»

Работает, очевидно, за O(N³). Естественно, такой подход не является оптимальным.

С использованием динамического программирования

Подробнее о динамическом программировании можно прочесть в этой статье. В таком случае, временная сложность составляет O(N²), требуется O(1) памяти. Если вы не знакомы с понятием «сложность алгоритма», настоятельно рекомендуем вначале изучить статью по этой теме. Идея алгоритма заключается в работе с массивом, где в позиции с индексом i, записано, какой максимальной длины есть палиндром с центром в i. Алгоритм решения задачи со схожей идеей можно найти на Wikibooks, а реализация именно такого решения есть на сайте programcreek.com, но на английском языке.

Быстрые алгоритмы

Быстрыми алгоритмами (за O(N)) решения этой задачи являются алгоритм Манакера, а также алгоритмы на суффиксном дереве с использованием быстрого алгоритма поиска LCA. Однако же эти алгоритмы являются довольно трудными для понимания, а подобная задача нехарактерна для больших объемов данных, так что для реального собеседования можно обойтись и более простыми вариантами.

Разбитие слова на словарные части

Задача: дано слово и словарь. Необходимо выяснить, существует ли способ разбить это слово на несколько частей, каждая из которых входит в словарь.

Наивный алгоритм

Мы рекомендуем отказаться от данного подхода в силу высокой сложности — O(2ⁿ).

Динамическое программирование

Сложность составляет O(N × L), где L — длина словаря. Требуется O(N) памяти. Пример такой реализации, конечно же, есть на programcreek.com и он, как вы догадываетесь, на английском языке.

Работа с регулярными выражениями

Регулярные выражения — гибкий инструмент поиска символьных последовательностей в строках. В большинстве языков программирования, если не во всех, существуют методы для работы с регулярными выражениями. В Java, например, это пакет java.util.regex. Единственное, что нужно программисту — научиться использовать эти методы. Для глубокого изучения темы можно почитать теорию конечных автоматов, на которых построены регулярные выражения, а познакомиться с «регулярками» можно в нашем вводном материале.

Словарная лестница

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

// Входные данные:
"hit"; "cog"; ["hot","dot","dog","lot","log"]
// Вариант получаемой в результате цепочки:
"hit" -> "hot" -> "dot" -> "dog" -> "cog"

Поиск в глубину

Начинать перебирать все варианты и спускаться ниже — не самый лучший способ. Такой метод называется «поиск в глубину». Чтобы такой алгоритм действительно давал кратчайший путь, а не первый в лексико-графическом порядке, потребуется O(N!), где N — длина словаря.

Поиск в ширину

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

Перевод строки в число

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

  • строка может быть пустой, а значит имеет смысл вернуть 0;
  • в начале строки могут быть пробелы;
  • у числа может быть знак «минус»;
  • число может быть в вещественной форме;
  • полученное число может выходить за границы типа.

Корректность скобочной последовательности

Задача: дана строка, в которой используются скобки разного типа. Необходимо проверить, является ли такая скобочная последовательность правильной. Неправильным будет, например, такое сочетание: ({)}.

В общем-то, здесь мы и применим наивный алгоритм, работающий за O(N): например, с использованием стека, куда помещаются встреченные скобки. Такое решение будет стоить O(N) памяти, но можно решить и за O(1) памяти, если завести счетчики для каждого типа скобок. В Java можно реализовать решение этой задачи используя Hashmap, как говорится на programcreek.com.

Проверка на палиндромность

При выполнении этой задачи нужно учитывать только буквы и цифры, но не учитывать регистр, иными словами, фраза «А роза упала на лапу Азора» является палиндромом.

Замечание Если этот вопрос попадется вам на собеседовании, лучше спросить, чем считать пустую строку. Мы считаем ее палиндромом.

На самом деле, решение этой задачи не очень сложное имы предлагаем аж два варианта.

Сначала обработать строку

Для начала можно пройтись по строке, оставив только буквы и цифры, чего требует условие и лишь затем наивным способом проверить, является ли эта строка палиндромом, что потребует O(N) времени.

Сразу проверить строку

Другой вариант — проверка строки без обработки. В этом случае мы заводим два указателя, инициализируемые началом и концом строки. Далее они движутся по строке, смещаясь к центру, пока не станут указывать на букву или цифру. Затем просто проверяем их на равенство. Продолжаем выполнение, пока левый указатель не станет больше правого. Очевидно, что это те же O(N), но здесь меньше константа.

Оба эти решения приведены на programcreek.com.

Длиннейшая подстрока без повторяющихся символов

На programcreek.com приведены два решения: наивное, за O(N²) времени и O(1) дополнительной памяти, а также с использованием HashMap. В Java обращение к HashMap составляет O(1), поэтому второе решение занимает O(N) времени, но требует больше памяти.

Однако, при реализации решения этой задачи на других языках программирования, где HashMap не является таким эффективным, будет необходимо обратиться к понятию z-функции. Тогда решение займет O(N) памяти (меньше, чем для HashMap) и O(N) времени.

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

Документация JDK 19 — Главная

  1. Главная
  2. Ява
  3. Java SE
  4. 19

Обзор

  • Прочтите меня
  • Примечания к выпуску
  • Что нового
  • Руководство по миграции
  • Загрузить JDK
  • Руководство по установке
  • Формат строки версии

Инструменты

  • Технические характеристики инструментов JDK
  • Руководство пользователя JShell
  • Руководство по JavaDoc
  • Руководство пользователя средства упаковки

Язык и библиотеки

  • Обновления языка
  • Основные библиотеки
  • HTTP-клиент JDK
  • Учебники по Java
  • Модульный JDK
  • Руководство программиста API бортового регистратора
  • Руководство по интернационализации

Технические характеристики

  • Документация API
  • Язык и ВМ
  • Имена стандартных алгоритмов безопасности Java
  • банок
  • Собственный интерфейс Java (JNI)
  • Инструментальный интерфейс JVM (JVM TI)
  • Сериализация
  • Проводной протокол отладки Java (JDWP)
  • Спецификация комментариев к документации для стандартного доклета
  • Прочие характеристики

Безопасность

  • Руководство по безопасному кодированию
  • Руководство по безопасности

Виртуальная машина HotSpot

  • Руководство по виртуальной машине Java
  • Настройка сборки мусора

Управление и устранение неполадок

  • Руководство по устранению неполадок
  • Руководство по мониторингу и управлению
  • Руководство по JMX

Client Technologies

  • Руководство по специальным возможностям Java

Даты в Scala 3: как преобразовать строки в даты (LocalDate, DateTimeFormatter)

Это отрывок из Scala Cookbook, 2-е издание. Это Рецепт 3.12, Разбор строк в даты .

Проблема

При использовании Scala (2 или 3) вам необходимо преобразовать строку в один из типов даты/времени, представленных в Java 8.

Решение

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

Scala и LocalDate

В этом примере показан формат по умолчанию для java.time.LocalDate :

  импортировать java.time.LocalDate
val d = LocalDate.parse("2020-12-10") // LocalDate = 2020-12-10  

Если вы попытаетесь передать строку в parse с неправильным форматом, вы получите исключение:

  val d = LocalDate.parse("2020/12/10") // java.time.format.DateTimeParseException  

Чтобы принять строку в другом формате, создайте средство форматирования для нужного шаблона:

  импорт java. time.format.DateTimeFormatter
val df = DateTimeFormatter.ofPattern("гггг/мм/дд")
val d = LocalDate.parse("2020/12/10", df) // LocalDate = 2020-12-10  

Scala и LocalTime

Эти примеры демонстрируют формат по умолчанию для java.time.LocalTime :

  импортировать java.time.LocalTime
val t = LocalTime.parse("01:02") //01:02
val t = LocalTime.parse("13:02:03") //13:02:03  

Обратите внимание, что каждое поле требует начального 0 :

  val t = LocalTime.parse("1:02") //java.time.format.DateTimeParseException
val t = LocalTime.parse("1:02:03") //java.time.format.DateTimeParseException  

Эти примеры демонстрируют несколько способов использования средств форматирования:

  импорт java.time.format.DateTimeFormatter
LocalTime.parse("00:00", DateTimeFormatter.ISO_TIME)
    // 00:00
LocalTime.parse("23:59", DateTimeFormatter. ISO_LOCAL_TIME)
    // 23:59
LocalTime.parse("23 59 59", DateTimeFormatter.ofPattern("ЧЧ мм сс"))
    // 23:59:59
LocalTime.parse ("11 59 59 PM", DateTimeFormatter.ofPattern ("чч мм сс а"))
    // 23:59:59  

Scala/LocalDateTime

Этот пример демонстрирует формат по умолчанию для java.time.LocalDateTime :

  импортировать java.time.LocalDateTime
вал с = "2021-01-01T12:13:14"
val ldt = LocalDateTime.parse(s) // LocalDateTime = 2021-01-01T12:13:14  

Эти примеры демонстрируют несколько способов использования средств форматирования:

  импортировать java.time.LocalDateTime
импортировать java.time.format.DateTimeFormatter

значение с = "1999-12-31 23:59"
val f = DateTimeFormatter.ofPattern("гггг-ММ-дд ЧЧ:мм")
val ldt = LocalDateTime.parse(s, f)
    // 1999-12-31T23:59

val s = "1999-12-31 23:59:59"
val f = DateTimeFormatter.ofPattern("гггг-ММ-дд чч:мм:сс а")
val ldt = LocalDateTime. parse(s, f)
    // 1999-12-31T23:59:59  

Scala/Instant

java.time.Instant имеет только один метод parse , который требует отметку даты/времени в правильном формате:

  импорт java.time.Instant
Instant.parse("1970-01-01T00:01:02.00Z") // 1970-01-01T00:01:02Z
Instant.parse("2021-01-22T23:59:59.00Z") // 2021-01-22T23:59:59Z  

Scala/ZonedDateTime

Эти примеры демонстрируют форматы по умолчанию для java.time.ZonedDateTime :

  импортировать java.time.ZonedDateTime

ZonedDateTime.parse("2020-12-31T23:59:59-06:00")
    // ZonedDateTime = 2020-12-31T23:59:59-06:00

ZonedDateTime.parse("2020-12-31T23:59:59-00:00[США/Гора]")
    // ZonedDateTime = 2020-12-31T16:59:59-07:00[US/Mountain]  

Эти примеры демонстрируют несколько способов использования средств форматирования с ZonedDateTime :

  импортировать java. time.ZonedDateTime
импортировать java.time.format.DateTimeFormatter._

val zdt = ZonedDateTime.parse("2021-01-01T01:02:03Z", ISO_ZONED_DATE_TIME)
    // ZonedDateTime = 2021-01-01T01:02:03Z

ZonedDateTime.parse("2020-12-31T23:59:59+01:00", ISO_DATE_TIME)
    // ZonedDateTime = 2020-12-31T23:59:59+01:00

ZonedDateTime.parse("2020-02-29T00:00:00-05:00", ISO_OFFSET_DATE_TIME)
    // ZonedDateTime = 2020-02-29T00:00-05:00

ZonedDateTime.parse("Сб, 29 февраля 2020 г., 00:01:02 по Гринвичу", RFC_1123_DATE_TIME)
    // ZonedDateTime = 2020-02-29T00:01:02Z  

Имейте в виду, что неправильная дата (или дата в неправильном формате) вызовет исключение:

  ZonedDateTime.parse("2021-02-29T00:00:00–05:00", ISO_OFFSET_DATE_TIME)
  // java.time.format.DateTimeParseException: текст '2021-02-29T00:00:00-05:00'
  // не удалось проанализировать: недопустимая дата «29 февраля», так как «2021» не является високосным годом

ZonedDateTime.parse("Пт, 29 февраля 2020 г. , 00:01:02 по Гринвичу", RFC_1123_DATE_TIME)
  // java.time.format.DateTimeParseException: текст
  // «Пт, 29 февраля 2020 г., 00:01:02 по Гринвичу» не удалось проанализировать: обнаружен конфликт:
  // Поле DayOfWeek 6 отличается от DayOfWeek 5, полученного из 2020-02-29 
этот пост спонсирован моими книгами:

#1 Новый релиз

FP Бестселлер

Выпущено в сентябре 2022 г.

Таким образом, если вы используете Scala 2 или Scala3 и вам нужно преобразовать строку в один из типов даты/времени, представленных в Java 8, я надеюсь, что это будет полезно.

Как анализировать строку как время в Go

Я много лет работаю Java разработчиком. Несколько месяцев назад я начал изучать Golang .

Одно из неожиданных различий между Java и Golang заключается в том, как разбирать строку на время.

В Java мы все знакомы с java.time.format.DateTimeFormatter и магическими буквами y , d , M , h , m 90 , и т. д. Когда я вижу строку, представляющую время или дату, я автоматически сопоставляю строку с шаблоном в своем уме.

 // строка
Строка s = "3 июня 2008 г. 11:05:30";
// шаблон
Шаблон строки = "д МММ гггг ЧЧ:мм:сс";
 

Однако в Golang это не так. Стандартный API анализа времени в пакете time :

 func Parse(макет, строка значения) (время, ошибка)
 

Принимает макет в качестве первого параметра. Что такое макет ? Документ не дает четкого определения. Это определенно не шаблон в Java.

В пакете time есть несколько предопределенных раскладок. Например:

 ANSIC = "Пн Янв _2 15:04:05 2006"
RFC3339 = "2006-01-02T15:04:05Z07:00"
 

Сначала я подумал: «Хорошо, макет просто выглядит как допустимое значение даты и времени». Код библиотеки Golang может быть достаточно умен, чтобы «угадать» формат даты и времени из «примера» ( layout ). Но, подождите секунду, что такое _ в макете ANSIC ? Также будут двусмысленные форматы без какого-либо конкретного контекста/правил. Например, если я задаю «макет» как «01/01/2007», как код узнает, где месяц, а где день?

Если вы внимательно прочитаете документ, вы поймете, что макет — это не просто произвольная дата и время. Есть правило о макете . В предопределенных макетах есть некоторые подсказки. Например, год указан как 2006 , а месяц — как январь (или январь , 01 ).

Правило определено/реализовано в функции nextStdChunk в формате.go. Мы можем перечислить все правила, прочитав код:

Фрагмент макета Формат
Январь stdLongMonth
Январь стдМесяц
Понедельник stdLongWeekDay
Пн stdWeekDay
МСТ стдТЗ
01 stdZeroMonth
02 stdZeroDay
03 stdZeroHour12
04 stdZeroMinute
05 stdZeroSecond
06 stdYear
002 stdZeroYearDay
15 стандартный час
1 стднуммесяц
2006 stdLongYear
2 stdDay
_2 stdUnderDay
_2006 stdLongYear
__2 stdUnderYearDay
3 stdHour12
4 стандартная минута
5 стандартная секунда
Вечер стандПМ
вечера станд. /мин
-070000 stdNumSecondsTz
-07:00:00 stdNumColonSecondsTZ
-0700 станднумтц
-07:00 stdNumColonTZ
-07 стднумшорттц
Z070000 stdISO8601SecondsTZ
Z07:00:00 stdISO8601ColonSecondsTZ
Z0700 стандарт ISO8601TZ
З07:00 stdISO8601ColonTZ
Z07 stdISO8601ShortTZ
.0 / .00 / .000 stdFracSecond0
0,9 / 0,99 / 0,999 stdFracSecond9

На основе приведенной выше таблицы совершенно ясно, что 01 в макете будет рассматриваться как месяц, а 02 будет днем ​​месяца. Таким образом, «01.01.2006» не будет работать в качестве макета, даже если это допустимая дата. Правильная раскладка должна быть 02.01.2006 (предположим, я хотел, чтобы формат даты был MM/dd/yyyy , Java здесь снова).

Как только вы поймете правило, написать макет будет легко. Единственная сложная часть — это часовой пояс. Вы должны использовать MST в качестве имени часового пояса, если строка включает трехбуквенную аббревиатуру часового пояса (это связано с тем, что MST — это UTC-07:00, что соответствует другим определениям блоков макета часового пояса). Чтобы легко запомнить правило компоновки, нам просто нужно помнить одну временную метку: 02.01.2006 04.03.05 MST (на английском языке: 2 января 2006 г., 15:04:05 по стандартному горному времени. Кстати, это понедельник и второй день года).

Я не совсем понимаю выбор чисел в раскладке. Кажется, это просто естественная последовательность 01, 02, 03, 04, 05, 06, 07.

Правило компоновки не поддерживает несколько редко используемых случаев, таких как квартал года, неделя года или неделя месяца и т. д. Однако в большинстве случаев оно работает. Кроме того, запоминание макета похоже на запоминание даты и времени. Это намного проще, чем запоминать все волшебные буквы в шаблонах формата даты и времени Java.

Чтобы разобрать строку как время в Golang , это так же просто, как:

 t1, ошибка := time.Parse(time.RFC3339, "2020-08-19T15:24:39-07:00")
если ошибка != ноль {
fmt.Println(ошибка.Ошибка())
}
fmt.Println(t1)
t2, err := time.Parse("02.01.2006 15:04:05 -07:00", "19.08.2020 15:24:39 -07:00")
если ошибка != ноль {
fmt.Println(ошибка.Ошибка())
}
fmt.Println(t2)
 

Вы получите тот же результат:

 2020-08-19 15:24:39 -07:00 по тихоокеанскому времени
2020-08-19 15:24:39 -07:00 по тихоокеанскому времени
 

Последняя защелка при использовании time.Parse заключается в том, что мы избегаем использования названных сокращений часовых поясов, таких как PDT , MST и т.