-
Notifications
You must be signed in to change notification settings - Fork 110
Locale-invariant parsing and formatting #251
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Closed
Closed
Changes from 92 commits
Commits
Show all changes
105 commits
Select commit
Hold shift + click to select a range
e517b81
WIP: first draft of locale-invariant parsing and formatting
dkhalanskyjb 9bb6ca8
Refactor: reify the string builder directives
dkhalanskyjb 324fd58
Refactoring: move the parser-combining logic to `Parser`
dkhalanskyjb 99a05a2
Fix parsing of years exceeding 4 digits
dkhalanskyjb 93391c2
Add some tests for common formats
dkhalanskyjb aab6f23
Fix UtcOffset parsing
dkhalanskyjb 273031f
Fix using complex string formats on Kotlin/Native
dkhalanskyjb 2cb10c4
Support LocalDateFormat.appendMonthName
dkhalanskyjb d78fdb1
Implement the Unicode format strings
dkhalanskyjb ab60f61
Implement 12-hour clock formats
dkhalanskyjb 6df67fc
Implement == for ValueBag
dkhalanskyjb 444d310
Implement formats with day of the week
dkhalanskyjb 0c5f27d
Implement the RFC 1123 format
dkhalanskyjb cc35b13
Redo the model of numeric signs to support multi-field values
dkhalanskyjb 7186e33
Work around some JS bug
dkhalanskyjb 35d867f
Implement pretty-printing for formatters
dkhalanskyjb aa76138
Rework the parser infrastructure for performance a bit
dkhalanskyjb ddb90aa
Introduce a common interface for date/time formats
dkhalanskyjb 9f44bc7
Support `find` and `findAll` on formats
dkhalanskyjb 2225bf2
Make "-" a non-special character in format strings
dkhalanskyjb fe1f03e
Refactor: gather all code for string representation of formatters
dkhalanskyjb 92c966f
Small refactoring
dkhalanskyjb c058b81
Introduce changes due to the first round of reviews
dkhalanskyjb d5ed029
Create entry points for formatting API like `LocalDate.Format.build`
dkhalanskyjb dc2098d
Implement upper bounds for ValueBag values
dkhalanskyjb dee428a
Remove the no-longer-needed code for the LRU cache
dkhalanskyjb 7c3096d
Remove the find and findAll functions
dkhalanskyjb 1158788
Add formatTo and parseOrNull
dkhalanskyjb 1161367
Add tests for assigning out-of-bounds values to ValueBag
dkhalanskyjb 7711596
Add tests for error handling on parsing
dkhalanskyjb 51e0c8a
Implement month and day-of-week name classes
dkhalanskyjb 0a46e36
Implement formats for two-digit year
dkhalanskyjb c05e34b
Reimplement padding as space/zero/none
dkhalanskyjb 2e23dab
Make the UTC offset hour contain the sign
dkhalanskyjb a9cd48b
*.Format.build { } -> *.Format { }
dkhalanskyjb 1849bb7
Disable configuring whether the year is output with a sign on padding…
dkhalanskyjb 49a277a
Refactoring to clear up the internal models
dkhalanskyjb 1b96711
Replace a single 'appendAlternatives' with clearer, orthogonal 'alter…
dkhalanskyjb 3450c85
Address the review
dkhalanskyjb 6cd875b
Work around a bug
dkhalanskyjb 37ad875
Implement predefined constants for popular formats
dkhalanskyjb a845d81
Clarify the semantics of formatting fractional values
dkhalanskyjb b0a076e
Make all the fields in a ValueBag independent from one another
dkhalanskyjb 86d912a
Implement appending whole formats in builders
dkhalanskyjb d049afc
Document everything
dkhalanskyjb a73e4aa
Add tests for timezone ID parsing and formatting
dkhalanskyjb 2529d49
Fix the code representation of the UTC offset hour
dkhalanskyjb f78a90d
Add a missing @SharedImmutable
dkhalanskyjb ac5d388
Typo: toLocaldate -> toLocalDate
dkhalanskyjb cd0841d
First stage of renaming
dkhalanskyjb 81a660f
Reorganize the entry points for the formatting API
dkhalanskyjb 4185fe8
Refactoring: remove a redundant class
dkhalanskyjb e9ec023
Second stage of renaming
dkhalanskyjb 3b573ea
Fixups
dkhalanskyjb 5d38ead
Remove a redundant annotation
dkhalanskyjb f3a9980
appendLiteral -> chars, char
dkhalanskyjb f751b9f
Add an OptIn for appendUnicodeFormatString
dkhalanskyjb 905b453
appendOptional -> optional
dkhalanskyjb ae1d624
Rename the parameters of alternativeParsing
dkhalanskyjb 97e8ff9
Reorganize the hierarchy of builders
dkhalanskyjb d8a1396
ValueBag -> DateTimeComponents
dkhalanskyjb 1ec4777
Implement formatAsKotlinBuilderDsl properly
dkhalanskyjb edad7f4
Print seconds in ISO constants for time and datetime
dkhalanskyjb 19a03a8
Rename DateTimeComponents functions
dkhalanskyjb 1a9ec34
Work around a segfault
dkhalanskyjb 0a0cf6c
Performance improvements
dkhalanskyjb da45897
Introduce benchmarks module with basic formatting benchmark
qwwdfsad acbb44d
Add README.md for benchmarks
qwwdfsad 603a483
Rename the remaining functions
dkhalanskyjb 288e976
Ensure that `optional` sets the fields to their default values
dkhalanskyjb c9c609d
Rework parsing to ensure a specific traversal order
dkhalanskyjb 90c9d37
Avoid copying in branches that never get entered
dkhalanskyjb 1d391f8
Hide the functionality to add extra zeros to the second's fraction
dkhalanskyjb f269b7a
Refactor the builder code
dkhalanskyjb 21a511d
Refactor
dkhalanskyjb 59fd382
Add tests for the Unicode patterns
dkhalanskyjb e5ff04e
Remove an unnecessary intermediate class
dkhalanskyjb 4047c07
Update the docs for byUnicodePattern
dkhalanskyjb 528aafe
Improve the error messages for incompatible Unicode directives
dkhalanskyjb 7b73212
Ensure that the value-is-reassigned error is not an exception
dkhalanskyjb 40542f5
Final touches to the docs
dkhalanskyjb 0af8ed5
Test that 60 seconds and 24 hours are not parsed for Instant
dkhalanskyjb f64f120
Adapt the code to the new Kotlin version
dkhalanskyjb 6bed380
Refactor a bit
dkhalanskyjb d6301ca
Remove the parser from Native
dkhalanskyjb 5bd918f
Add diagnostic messages
dkhalanskyjb 84e7d81
Support string constants that begin or end with numbers
dkhalanskyjb 122dd9c
Address the review
dkhalanskyjb db723fa
Address more review points
dkhalanskyjb d552935
Do not add trailing zeros to the fractions of seconds in standard for…
dkhalanskyjb a13e228
Mention the overloads of secondFraction() in the docs
dkhalanskyjb 24d8ae8
Don't support DecimalFraction.hashCode
dkhalanskyjb 3f5095b
Convert `y` to `u` automatically, but emit a comment about it
dkhalanskyjb 853ddc7
Mention the rounding mode in `secondFraction` docs
dkhalanskyjb 1ce9d14
Check that we can replicate java.time.Instant.parse
dkhalanskyjb b5236ed
Update README to include parsing and formatting
dkhalanskyjb f07c80e
Remove String.toSomething
dkhalanskyjb 70fb30c
Only allow the ISO extended format in `UtcOffset.parse`
dkhalanskyjb 7f73ac2
Use a single `parse` overload with a default parameter
dkhalanskyjb a6350ac
Fix a bug in byUnicodePattern that made optional sections mandatory
dkhalanskyjb 071867d
Fix how `formatAsKotlinBuilderDsl` formats pre-defined formats.
dkhalanskyjb 7d2a8fc
Add byUnicodePattern instructions to the README
dkhalanskyjb e270480
Change 'secondFraction' to truncate instead of rounding
dkhalanskyjb 825ccde
Make ISO_DATE_TIME_OFFSET more consistent with other ISO formats, doc…
dkhalanskyjb e0598c1
Refactor a test
dkhalanskyjb File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -4,4 +4,5 @@ | |
*.iml | ||
target | ||
build | ||
/local.properties | ||
/local.properties | ||
benchmarks.jar |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,28 @@ | ||
### Benchmarks utility module | ||
|
||
Module that provides benchmarking infrastructure for kotlinx-datetime. | ||
Please note that these benchmarks are typically written with the specific target, hypothesis and effect in mind. | ||
|
||
They provide numbers, not insights, and shouldn't be used as the generic comparison and statements like | ||
"X implementaiton or format is faster/slower than Y" | ||
|
||
|
||
#### Usage | ||
|
||
``` | ||
// Build `benchmarks.jar` into the project's root | ||
./gradlew :benchmarks:jmhJar | ||
|
||
// Run all benchmarks | ||
java -jar benchmarks.jar | ||
|
||
// Run dedicated benchmark(s) | ||
java -jar benchmarks.jar Formatting | ||
java -jar benchmarks.jar FormattingBenchmark.formatIso | ||
|
||
// Run with the specified number of warmup iterations, measurement iterations, timeunit and mode | ||
java -jar benchmarks.jar -wi 5 -i 5 -tu us -bm thrpt Formatting | ||
|
||
// Extensive help | ||
java -jar benchmarks.jar -help | ||
``` |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,34 @@ | ||
/* | ||
* Copyright 2019-2023 JetBrains s.r.o. and contributors. | ||
* Use of this source code is governed by the Apache 2.0 License that can be found in the LICENSE.txt file. | ||
*/ | ||
|
||
plugins { | ||
id("kotlin") | ||
id("me.champeau.jmh") | ||
} | ||
|
||
|
||
val mainJavaToolchainVersion by ext(project.property("java.mainToolchainVersion")) | ||
val modularJavaToolchainVersion by ext(project.property("java.modularToolchainVersion")) | ||
|
||
sourceSets { | ||
dependencies { | ||
implementation(project(":kotlinx-datetime")) | ||
implementation("org.openjdk.jmh:jmh-core:1.35") | ||
} | ||
} | ||
|
||
// Publish benchmarks to the root for the easier 'java -jar benchmarks.jar` | ||
tasks.named<Jar>("jmhJar") { | ||
val nullString: String? = null | ||
archiveBaseName.set("benchmarks") | ||
archiveClassifier.set(nullString) | ||
archiveVersion.set(nullString) | ||
archiveVersion.convention(nullString) | ||
destinationDirectory.set(file("$rootDir")) | ||
} | ||
|
||
repositories { | ||
mavenCentral() | ||
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,27 @@ | ||
/* | ||
* Copyright 2019-2023 JetBrains s.r.o. and contributors. | ||
* Use of this source code is governed by the Apache 2.0 License that can be found in the LICENSE.txt file. | ||
*/ | ||
|
||
package kotlinx.datetime | ||
|
||
import org.openjdk.jmh.annotations.* | ||
import java.util.concurrent.* | ||
|
||
@Warmup(iterations = 5, time = 1) | ||
@Measurement(iterations = 5, time = 1) | ||
@BenchmarkMode(Mode.Throughput) | ||
@OutputTimeUnit(TimeUnit.MICROSECONDS) | ||
@State(Scope.Benchmark) | ||
@Fork(1) | ||
open class FormattingBenchmark { | ||
|
||
private val localDateTime = LocalDateTime(2023, 11, 9, 12, 21, 31, 41) | ||
private val formatted = LocalDateTime.Formats.ISO.format(localDateTime) | ||
|
||
@Benchmark | ||
fun formatIso() = LocalDateTime.Formats.ISO.format(localDateTime) | ||
|
||
@Benchmark | ||
fun parseIso() = LocalDateTime.Formats.ISO.parse(formatted) | ||
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is it useful to commit the benchmark set in this state?
Also, I'd prefer if we dogfood kotlinx-benchmark here.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I do run them occasionally.
Maybe we could do that, but I think it's a problem for after we've published a release with this PR.
Uh oh!
There was an error while loading. Please reload this page.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Just know that kotlinx-benchmark is not ready outside of JVM. Too many issues still, especially in JS.
But I'd be happy to see it adopted here, it may speed up the resolution of such issues.